So gehen Sie mit Leerzeichen in Dateinamen in Git Bash um

So gehen Sie mit Leerzeichen in Dateinamen in Git Bash um

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, findwith zu verwenden -print0und 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 grepauf mehreren Dateien laufen zu lassen:

shopt -s nullglob
shopt -s globstar
grep "api/" **/*.log **/*.err **/*.out

Aktiviert hier globstardie rekursive Zuordnung von Verzeichnissen mit **. Sie sollten dies festlegen, nullglobum 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 fordie Ausgabe von find(oder lsoder 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 barund b, dann würde die Zeile wie folgt ausgewertet:

for logfile in a foo bar b; do

Offensichtlich wird Bash logfileauf 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 -print0Option bewirkt) und die Ausgabe dann erneut basierend auf diesem Zeichen aufzuteilen NUL(was die Option „ -d ''in“ readbewirkt).

verwandte Informationen