![So gehen Sie mit Leerzeichen in Dateinamen in Git Bash um](https://rvso.com/image/1558675/So%20gehen%20Sie%20mit%20Leerzeichen%20in%20Dateinamen%20in%20Git%20Bash%20um.png)
Ich habe das folgende Skript geschrieben, um es unter Git Bash unter Windows 7 auszuführen:
#!/usr/bin/env sh
for logfile in `find -name "*.log" -o -name "*.err" -o -name "*.out"`
do
echo $logfile
grep "api/" "$logfile"
done
Das Problem ist, dass grep abstürzt, wenn ein Dateiname ein Leerzeichen enthält. Ich dachte, die Anführungszeichen sollten das beheben, aber das funktioniert nicht.
Ideen?
Antwort1
Lösung 1
Die beste Lösung besteht darin, find
with zu verwenden -print0
und die Ausgabe mit zu lesen while read …
:
find -name "*.log" -o -name "*.err" -o -name "*.out" -type f -print0 | while IFS= read -r -d '' logfile; do
...
Verwenden Sie sie weiterhin "$logfile"
mit Anführungszeichen, wie Sie es immer bei der Verwendung von Variablen tun sollten.
Lösung 2
Eine andere Lösung wäre, es find
überhaupt nicht zu verwenden und es einfach grep
auf mehreren Dateien laufen zu lassen:
shopt -s nullglob
shopt -s globstar
grep "api/" **/*.log **/*.err **/*.out
Aktiviert hier globstar
die rekursive Zuordnung von Verzeichnissen mit **
. Sie sollten dies festlegen, nullglob
um Fehler zu vermeiden, wenn eine dieser Dateierweiterungen nicht vorhanden ist.
Dies funktioniert jedoch nur für eine begrenzte Anzahl von Dateien, da möglicherweise die maximale Länge der Befehlszeilenargumente erreicht wird.
Warum tritt der Fehler auf?
Sie sollten niemals for
die Ausgabe von find
(oder ls
oder einer anderen Funktion ausführen, die Dateinamen mit Leerzeichen ausgibt). LesenDieser ArtikelWeitere Informationen dazu, warum dies ein Problem darstellt und wie es gelöst werden kann.
Kurz gesagt, Bash teilt Argumente durch Leerzeichen auf. Stellen Sie sich vor, Sie haben drei Dateien, a
, foo bar
und b
, dann würde die Zeile wie folgt ausgewertet:
for logfile in a foo bar b; do
Offensichtlich wird Bash logfile
auf a
, foo
, bar
, und setzen b
, was nicht das ist, was Sie wollten. Wenn Sie die Eingabe manuell auf angeben könnten for
, würden Sie diese Dateinamen in Anführungszeichen setzen, um das Problem zu lösen.
Um dies automatisch zu tun, besteht die Lösung darin, diese Dateinamen mit einem Zeichen abzugrenzen NUL
(was die -print0
Option bewirkt) und die Ausgabe dann erneut basierend auf diesem Zeichen aufzuteilen NUL
(was die Option „ -d ''
in“ read
bewirkt).