Konvertieren Sie XLS / XLSX-Tabellen anhand einer Liste in mehrere CSV-Tabellen

9

Ich muss alle Blätter einer einzelnen XLS / XLSX-Datei in eine CSV-Datei konvertieren. Dies erfolgt für alle XLS-Dateien in allen Verzeichnissen und Unterverzeichnissen (rekursiv).

Schritt 1 : Holen Sie sich die Blattnamen aller .xls in eine .csv mit:

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

filename-sheetnames-list.csv kann als Liste dienen:

sheetname1
sheetname2
sheetname3

Schritt 2 : Der Code zum Konvertieren eines bestimmten Blattes in eine CSV-Datei mit in2csv lautet:

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

Wie kann ich jeden Blattnamen in einer .xls / x-Datei abrufen und jedes Blatt separat für alle Verzeichnisse schreiben, die eine .xls / x enthalten?

in2csv --write-sheets "-" filename.xls > filename-sheet1.csv filename-sheet2.csv .... Gibt die Ausgabe nur auf sheet1.csv aus, nicht sicher, wie alle Blätter daraus abgerufen werden sollen.

csheth
quelle
2
Warum nicht einfach jedes Blatt mit findjedem .xls{,x}Schleifen durchlaufen -exec?
Dessert
1
@glennjackman das ist hier perfekt zum Thema, genau wie unter Unix & Linux .
Terdon

Antworten:

9

Sie können einfach eine Schleife in eine andere Schleife einfügen.

Verwenden Sie nicht formit findErgebnissen, um Fehler zu vermeiden .

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
quelle
@ Guru ah Mist. Du hast absolut recht. Ich hatte in einer Umgebung getestet, in der das IFS bereits geändert worden war, sodass es sich natürlich nach unten ausbreitete. Idiot . Danke, Bearbeitung rückgängig gemacht.
Terdon
@RoVo die erste Option funktioniert gut. Der zweite gibt mir jedoch keine Ausgabe oder Fehler. Ich bin mir nicht sicher warum; für eine einzelne .xls in2csv --write-sheets "-" filename.xls > sheetname.csvgibt nur das erste blatt. Ich weiß nicht, welche zusätzlichen Informationen ich hinzufügen soll, um alle Blätter zu schreiben. Das soll uns Hinweise geben, um Ihren Code zu korrigieren.
csheth
1
Haben Sie auf diese Version 1.0.2 aktualisiert? pip install csvkit -U. Ich denke, die Art und Weise, wie es funktioniert, ist nicht das, was Sie mögen. Mit dem einfachen Skript ab der ersten Option haben Sie mehr Möglichkeiten, die Ausgabe und die Dateinamen usw. zu steuern
pLumo
funktioniert immer noch nicht mit dem Update, und ja, ich würde es vorziehen, eine Liste zu verwenden, als --write-sheets Vielleicht können Sie diese alternative Option als andere Antwort festlegen ... Ich werde dann die erste Option als Antwort akzeptieren. Danke @RoVo
csheth
1
Vielleicht ist es im Allgemeinen eine gute Idee, alternative Optionen in einer anderen Antwort zu haben. Danke, froh, dass ich helfen konnte.
pLumo
6

Überspringen der Suche und Verwendung von 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
quelle
Dieses Skript sieht elegant aus, aber seine Ausgabe filename-{}.csventhält keine Daten. Ich bin ein Neuling und kann den Fehler nicht finden, indem ich das Skript bearbeite und nachlese. Etwas Hilfe?
csheth
@ChintanSheth mein schlechtes, ich hatte vergessen, dass die Umleitung draußen sein würde xargs. Korrigiert, jetzt nicht mehr so ​​elegant.
Muru
xargsund >ist böse :-P. Deshalb bevorzuge ich eine andere Schleife, die weniger fehleranfällig ist.
pLumo
@RoVo Normalerweise hätte ich auch eine andere Schleife gewählt, wollte hier nur eine andere Methode zeigen.
Muru
Dies funktioniert jetzt, jedoch etwas langsamer als die Antwort von @RoVo.
csheth
3

csvkit version> 1.0.2 verfügt über eine integrierte Funktion zum Schreiben aller Blätter:

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

Sie können also Folgendes versuchen:

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

Hinweis:

Dies scheint nicht wie erwartet zu 100% zu funktionieren. Aber einen Versuch wert und da dies die erste Version mit dieser Option ist, ist die Implementierung in zukünftigen Versionen möglicherweise besser / einfacher.

pLumo
quelle
0

Verwendung Gnumeric:

ssconvert -S filename.xlsx filename.csv

um eine csvDatei pro Blatt zu erhalten.

James Hirschorn
quelle