wie man mit bash * übereinstimmt, wenn es keine Übereinstimmungen gibt?

2063
kfmfe04

Das folgende Bash-Snippet funktioniert gut, wenn sich tatsächlich *.txtDateien im Verzeichnis befinden.

for txt in *.txt do  echo "loading data from $txt" done  

Wenn nicht, *.txtfällt das Literal als $ txt (nicht gut) in die Schleife.

Wie ändere ich diesen Code, damit *.txtder do ... doneBlock übersprungen wird, wenn keine Dateien vorhanden sind ?

6
`if [" * .txt "! = '* .txt']; dann machen Sie eine Schleife hier; fi` ott-- vor 11 Jahren 1
@ ott-- +1 für eine alternative Lösung kfmfe04 vor 11 Jahren 0
@ott: `[" * .txt "! = '* .txt']` ist immer falsch - beide Zeichenfolgen sind in Anführungszeichen, daher wird keine der beiden auf Übereinstimmungen geprüft. Wenn Sie die Anführungszeichen von einem entfernen, hat es andere Probleme. Gordon Davisson vor 11 Jahren 1
@GordonDavisson +1 für diesen Hinweis: Shell-Scripting scheint voller Überraschungen zu sein ... kfmfe04 vor 11 Jahren 0
@GordonDavisson Tatsächlich muss die Arbeit in zwei Schritten erfolgen: `files = $ (echo * .txt)` und dann: `if [" $ "! = '* .Txt']; dann`. ott-- vor 11 Jahren 1
@ott: Das würde funktionieren (mit Ausnahme des ungeraden Falls, wenn es eine einzige Datei gibt, die eigentlich "* .txt" heißt). Gordon Davisson vor 11 Jahren 0
Übrigens, kann als einzelne Zeile ausgeführt werden: `if [" $ (echo * .txt) "! = '* .Txt')]; dann` John Hascall vor 5 Jahren 0

2 Antworten auf die Frage

8
kfmfe04

Sieht aus, als hätte Google die Antwort auf diese Frage gefunden.

Setzen Sie diesen magischen Zauber vor die forAussage:

shopt -s nullglob 
4
Gordon Davisson

Die Nullglob-Option (@ kfmfe04s Antwort) ist am besten, wenn Sie bash (keine Brand-X-Shell) verwenden und sich keine Gedanken darüber machen müssen, dass Nullglob etwas anderes ändert oder beschädigt. Ansonsten können Sie diese (etwas unordentlicher) Option verwenden:

for txt in *.txt do [ -e "$txt" ] || continue echo "loading data from $txt" done 

Dies überspringt automatisch Dateien, die nicht vorhanden sind (hauptsächlich "* .txt", wenn keine Übereinstimmungen vorhanden waren, aber möglicherweise auch Dateien, die zwischen dem forGenerieren der Liste und dem Zeitpunkt, zu dem die Schleife zu ihnen kam, gelöscht wurden ...)

Eine Datei wird möglicherweise zwischen dem Aufruf "-e" und der späteren Verarbeitung gelöscht. Koterpillar vor 5 Jahren 0
@Koterpillar Richtig, das Testen von "-e" verringert jedoch das Zeitfenster, in dem das Löschen ein Problem darstellt. Gordon Davisson vor 5 Jahren 0