Konversikan spreadsheet .xls / .xlsx ke beberapa .csv berdasarkan daftar

9

Saya perlu mengonversi semua lembar file .xls / .xlsx menjadi .csv. Ini akan dilakukan pada semua file .xls di semua direktori dan sub-direktori (secara rekursif).

Langkah 1 : Dapatkan nama-nama sheet dari semua .xls ke dalam .csv menggunakan:

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

filename-sheetnames-list.csv dapat bertindak sebagai daftar:

sheetname1
sheetname2
sheetname3

Langkah 2 : Kode untuk mengonversi lembar tertentu menjadi .csv menggunakan in2csv adalah:

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

Bagaimana saya bisa mendapatkan setiap sheetname dalam .xls / x dan menulis setiap sheet secara terpisah untuk semua direktori yang mengandung .xls / x?

in2csv --write-sheets "-" filename.xls > filename-sheet1.csv filename-sheet2.csv .... memberikan output hanya pada sheet1.csv, tidak yakin bagaimana mendapatkan semua sheet dari ini.

csheth
sumber
2
Mengapa tidak hanya findsetiap .xls{,x}dan menggunakan setiap lembar -exec?
hidangan penutup
1
@glennjackman ini sempurna pada topik di sini, sama seperti di Unix & Linux .
terdon

Jawaban:

10

Anda bisa meletakkan lingkaran di dalam lingkaran lain.

Untuk menghindari kesalahan, jangan gunakan fordengan findhasil.

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')
pLumo
sumber
@muru ah sial. Anda benar sekali. Saya sudah menguji di lingkungan di mana IFS sudah diubah jadi tentu saja itu menyebar ke bawah. Idiot . Terima kasih, edit dikembalikan.
terdon
@RoVo opsi pertama berfungsi dengan baik. Namun yang kedua tidak memberi saya output atau kesalahan. Saya tidak yakin mengapa; untuk satu .xls in2csv --write-sheets "-" filename.xls > sheetname.csvhanya memberikan lembar pertama. Saya tidak tahu info tambahan apa yang ditambahkan untuk menulis semua lembar. Itu akan memberi kami petunjuk untuk memperbaiki kode Anda.
csheth
1
Apakah Anda memperbarui ke versi 1.0.2? pip install csvkit -U. Saya pikir cara kerjanya tidak seperti yang Anda suka, dengan skript sederhana dari opsi 1 Anda memiliki lebih banyak cara untuk mengontrol output dan nama file dll.
pLumo
masih tidak berfungsi dengan pembaruan, dan ya saya lebih suka menggunakan daftar daripada --write-sheets Mungkin Anda dapat mengatur opsi alternatif ini sebagai jawaban lain ... Saya akan menerima opsi pertama sebagai jawabannya. Terima kasih @RoVo
csheth
1
Mungkin umumnya ide yang bagus untuk memiliki opsi alternatif di jawaban lain. Terima kasih, senang saya bisa membantu.
pLumo
6

Melewati mencari dan menggunakan 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
muru
sumber
skrip ini terlihat elegan tetapi hasilnya tidak filename-{}.csvmengandung data. Saya seorang pemula dan sepertinya tidak dapat menemukan kesalahan dengan mengedit skrip dan membaca. Beberapa bantuan?
csheth
@ ChintanSheth badku, aku lupa pengalihan akan berada di luar xargs. Diperbaiki, tidak seanggun sekarang.
muru
xargsdan >itu jahat :-P. Itu sebabnya saya lebih suka loop lain, lebih sedikit rawan kesalahan.
pLumo
@RoVo Saya biasanya pergi untuk loop lain juga, hanya ingin menunjukkan metode lain di sini.
muru
Ini berfungsi sekarang, namun sedikit lebih lambat dari jawaban @RoVo.
csheth
3

versi csvkit> 1.0.2 memiliki fungsi bawaan untuk menulis semua sheet:

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

Jadi, Anda bisa mencoba yang berikut:

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

catatan:

Ini sepertinya tidak bekerja 100% seperti yang diharapkan. Tetapi patut dicoba dan karena ini adalah versi pertama dengan opsi itu mungkin di versi mendatang implementasinya lebih baik / mudah.

pLumo
sumber
0

Gunakan Gnumeric:

ssconvert -S filename.xlsx filename.csv

untuk mendapatkan satu csvfile per lembar.

James Hirschorn
sumber