Linux-Shell-Skript für jede Datei in einem Verzeichnis Holen Sie sich den Dateinamen und führen Sie ein Programm aus

83

Szenario:

Ein Ordner im Linux-System. Ich möchte jede XLS-Datei in einem Ordner durchlaufen.

Dieser Ordner besteht normalerweise aus verschiedenen Ordnern und Dateitypen (.sh, .pl, .csv, ...).

Ich möchte nur alle Dateien im Stammverzeichnis durchlaufen und ein Programm nur für XLS-Dateien ausführen.

Bearbeiten:

Das Problem ist, dass das Programm, das ich ausführen muss, 'xls2csv' ist, um vom XLS- ins CSV-Format zu konvertieren. Also muss ich für jede XLS-Datei den Dateinamen abrufen und an CSV anhängen.

Zum Beispiel habe ich eine test.xls-Datei und die Argumente für xls2csv sind: xls2csv test.xls test.csv

Habe ich Sinn gemacht?

ThinkCode
quelle

Antworten:

196

Bash:

for f in *.xls ; do xls2csv "$f" "${f%.xls}.csv" ; done
Ignacio Vazquez-Abrams
quelle
Einfach toll! Funktioniert perfekt! Ich danke dir sehr!
ThinkCode
6
Genau das habe ich aus einem ganz anderen Grund gesucht. Ein wenig Bearbeitung, und es ist perfekt für meine spezifischen Bedürfnisse. Thanks = D Und für alle, denen nicht klar ist, was dies bewirkt: $ {f% .ext} ersetzt den Dateinamen ohne die Erweiterung, sodass in diesem Beispiel "filename.csv" anstelle von "filename" angezeigt wird. xls.csv ".
Frungi
Heh ich googelte "Linux foreach txt file" und fand dies. Dies war genau das, was ich brauchte, ich habe tatsächlich versucht, xls2csv zu verwenden, aber ich dachte, ich würde keine Ergebnisse finden, die danach suchen :)
akiller
1
$ f hat den Wert * .xls, wenn die * .xls keiner Datei entsprechen. Überprüfen Sie meine Antwort, wenn das ein Problem ist.
Andrew Bourgeois
Oder Sie können einfach einstellen nullglob, um die Schleife zu überspringen.
Ignacio Vazquez-Abrams
14
for i in *.xls ; do 
  [[ -f "$i" ]] || continue
  xls2csv "$i" "${i%.xls}.csv"
done

Die erste Zeile in der doDatei prüft, ob die "übereinstimmende" Datei wirklich vorhanden ist, denn falls in Ihrer Datei nichts übereinstimmt for, dowird die mit "* .xls" als ausgeführt $i. Das könnte für Sie schrecklich sein xls2csv.

Andrew Bourgeois
quelle
12

Schauen Sie sich den Befehl find an .

Was Sie suchen, ist so etwas wie

find . -name "*.xls" -type f -exec program 

Hat es geposted

find . -name "*.xls" -type f -exec xls2csv '{}' '{}'.csv;

wird ausgeführt xls2csv file.xls file.xls.csv

Näher an dem, was Sie wollen.

Tom
quelle
find -maxdepth 1Unterordner ausschließen. Dies wird auch test.xlsin test.xls.csvstatt konvertiert test.csv. Also nicht ganz das, wonach OP gefragt hat, aber ziemlich nah.
Ephemient
Die Verwendung {}als Teilzeichenfolge eines Arguments anstelle eines gesamten Arguments ist eine GNU-Erweiterung, die von der POSIX-Spezifikation für nicht garantiert wird find. Daher ist diese Antwort nicht unbedingt auf Nicht-GNU-Plattformen übertragbar.
Charles Duffy
4
find . -type f -name "*.xls" -printf "xls2csv %p %p.csv\n" | bash

Bash 4 (rekursiv)

shopt -s globstar
for xls in /path/**/*.xls
do
  xls2csv "$xls" "${xls%.xls}.csv"
done
Ghostdog74
quelle
Hervorragende Lösung. Ich habe dies verwendet, um Haml / scss zu schreiben und zur Entwurfszeit für ein node.js-Projekt in html / css zu integrieren.
Chris Kemp
1
Dies ist geradezu gefährlich, wenn Sie Ihren Dateinamen nicht vertrauen, dass sie keine Dinge wie $(rm -rf /)... oder nur Leerzeichen enthalten.
Charles Duffy