แปลง. xls / .xlsx สเปรดชีตเป็น. csv หลายรายการตามรายการ


10

ฉันต้องแปลงไฟล์. xls / .xlsx ทั้งหมดเป็นไฟล์. csv สิ่งนี้จะทำในไฟล์. xls ทั้งหมดในทุกไดเรกทอรีและไดเรกทอรีย่อย (ซ้ำ)

ขั้นตอนที่ 1 : รับแผ่นชื่อของ. xls ทั้งหมดเป็น. csv โดยใช้:

for file in $(find . -name '*.xls' -o -name '*.xlsx');do in2csv -n "$file" > ${file%.xls}-sheetnames-list.csv; done

filename-sheetnames-list.csv สามารถทำหน้าที่เป็นรายการ:

sheetname1
sheetname2
sheetname3

ขั้นตอนที่ 2 : รหัสสำหรับการแปลงชีทที่เฉพาะเจาะจงให้เป็น. csv โดยใช้ in2csv คือ:

in2csv --sheet "SHEETNAME" filename.xls > filename-SHEETNAME.csv

ฉันจะรับทุกชื่อชีตใน. xls / x และเขียนทุกชีตแยกจากกันสำหรับไดเรกทอรีทั้งหมดที่มี. xls / x ได้อย่างไร

in2csv --write-sheets "-" filename.xls > filename-sheet1.csv filename-sheet2.csv .... ให้ผลลัพธ์เฉพาะใน sheet1.csv ไม่แน่ใจว่าจะรับชีตทั้งหมดได้อย่างไร


2
ทำไมไม่เพียงfindทุก.xls{,x}และห่วงกว่าแผ่นโดยใช้ทุก-exec?
ของหวาน

1
@glennjackman นี้เป็นอย่างดีในหัวข้อที่นี่เพียงที่มันจะอยู่บนระบบปฏิบัติการยูนิกซ์และลินุกซ์
terdon

คำตอบ:


10

คุณสามารถใส่ลูปเข้าไปในลูปอื่นได้

เพื่อหลีกเลี่ยงข้อผิดพลาดอย่าใช้forกับfindผลลัพธ์

while IFS= read -r file; do
    while IFS= read -r sheet; do
        in2csv --sheet "$sheet" "$file" > "${file%.*}-${sheet}.csv"
    done < <(in2csv -n "$file")
done < <(find . -name '*.xls' -o -name '*.xlsx')

@muru อึอึ คุณพูดถูก ฉันได้ทดสอบในสภาพแวดล้อมที่ IFS มีการเปลี่ยนแปลงไปแล้วแน่นอนว่ามันแพร่กระจายลงไป คนบ้า ขอขอบคุณแก้ไขอีกครั้ง
terdon

@RoVo ตัวเลือกแรกทำงานได้ดี อย่างไรก็ตามอันที่สองให้ฉันไม่มีผลลัพธ์หรือข้อผิดพลาด ฉันไม่แน่ใจว่าทำไม; สำหรับแผ่นเดียว.xls in2csv --write-sheets "-" filename.xls > sheetname.csvให้เพียงแผ่นแรก ฉันไม่ทราบว่าจะเพิ่มข้อมูลใดในการเขียนแผ่นงานทั้งหมด ที่จะให้เบาะแสเราเพื่อแก้ไขรหัสของคุณ
csheth

1
คุณอัปเดตเป็นเวอร์ชั่น 1.0.2 แล้วหรือยัง? pip install csvkit -U. ฉันคิดว่าวิธีการทำงานไม่ใช่สิ่งที่คุณต้องการด้วย skript แบบง่าย ๆ จากตัวเลือกที่ 1 คุณมีวิธีควบคุมเอาต์พุตและชื่อไฟล์อื่น ๆ อีกมากมาย
pLumo

ยังคงใช้งานไม่ได้กับการอัปเดตและใช่ฉันต้องการใช้รายการมากกว่า--write-sheets บางทีคุณสามารถตั้งค่าตัวเลือกอื่นเป็นคำตอบอื่นได้ ... ฉันจะยอมรับตัวเลือกแรกเป็นคำตอบแล้ว ขอบคุณ @RoVo
csheth

1
อาจเป็นความคิดที่ดีที่จะมีทางเลือกอื่นในคำตอบอื่น ขอบคุณดีใจที่ฉันสามารถช่วย
pLumo

7

ข้ามการค้นหาและการใช้ bash:

shopt -s globstar  # enable recursive globbing
for f in **/*.xls{,x}  # for files ending in .xls or .xlsx
do
    in2csv -n "$f" |   # get the sheetnames
      xargs -I {} bash -c 'in2csv --sheet "$2" "$1" > "${1%.*}"-"$2".csv' _ "$f" {} # {} will be replaced with the sheetname
done

สคริปต์นี้ดูสวยงาม แต่ผลลัพธ์ของมันfilename-{}.csvไม่มีข้อมูล ฉันเป็นสามเณรและไม่สามารถหาข้อผิดพลาดได้โดยแก้ไขสคริปต์และอ่าน ความช่วยเหลือ?
csheth

@ChintanSheth xargsที่ไม่ดีของฉันฉันลืมเปลี่ยนเส้นทางจะออกไปข้างนอก ถูกต้องแล้วไม่สวยสง่าในตอนนี้
muru

xargsและ>เป็นสิ่งที่ชั่วร้าย :-P นั่นเป็นเหตุผลที่ฉันชอบวงอื่นมันมีข้อผิดพลาดน้อยลง
pLumo

@RoVo ฉันมักจะไปวนซ้ำอีกด้วยอยากแสดงวิธีอื่นที่นี่
muru

ใช้งานได้ในขณะนี้ แต่ช้ากว่า @RoVo คำตอบเล็กน้อย
csheth

3

รุ่น csvkit> 1.0.2มีฟังก์ชั่น builtin เพื่อเขียนชีตทั้งหมด:

--write-sheets: WRITE_SHEETS
                      The names of the Excel sheets to write to files, or
                      "-" to write all sheets.

ดังนั้นคุณสามารถลองต่อไปนี้:

find . -name '*.xls' -o -name '*.xlsx' -exec in2csv --write-sheets "-" {} \;

บันทึก:

ดูเหมือนว่าจะไม่ทำงาน 100% ตามที่คาดไว้ แต่ควรลองดูและเนื่องจากนี่เป็นเวอร์ชั่นแรกที่มีตัวเลือกนั้นอาจเป็นเวอร์ชันในอนาคตการใช้งานจะดีกว่า / ง่ายกว่า


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.