Wechseln Sie von der Bourne-Shell ( /bin/bash
) zur Bourne-Shell ( /bin/sh
), und eine einfache Lösung wird möglich.
Die bash(1)
Manpage erwähnt die Nullglob- Option:
Wenn gesetzt, erlaubt bash Mustern, die mit keiner Datei übereinstimmen (siehe Pfadnamenerweiterung oben), zu einer Nullzeichenfolge zu expandieren.
Der Abschnitt zur Erweiterung des Pfadnamens sagt:
Nach dem Wort Spaltung scannt ... bash jedes Wort für die Zeichen *, ? und [ . Wenn eines dieser Zeichen erscheint, wird das Wort als Muster betrachtet und durch eine alphabetisch sortierte Liste von Dateinamen ersetzt, die dem Muster entsprechen. Wenn keine übereinstimmenden Dateinamen gefunden werden und die Shell-Option nullglob nicht aktiviert ist, bleibt das Wort unverändert. Wenn die Option nullglob gesetzt ist und keine Übereinstimmungen gefunden werden, wird das Wort entfernt.
Wenn Sie also die Nullglob- Option festlegen, wird das gewünschte Verhalten für Muster festgelegt. Wenn keine Datei mit dem Muster übereinstimmt, wird die Schleife nicht ausgeführt.
#!/bin/bash shopt -s nullglob for f in *.ext; do handle "$f" done
Die Option nullglob kann jedoch das gewünschte Verhalten für andere Befehle beeinträchtigen. Daher ist es wahrscheinlich ratsam, die vorhandene Einstellung von nullglob zu speichern und anschließend wiederherzustellen. Glücklicherweise gibt der shopt -p
integrierte Befehl die Ausgabe in einer Form aus, die als Eingabe wiederverwendet werden kann. Es gibt jedoch eine Ausgabe für alle Optionen grep
aus. Verwenden Sie also die Einstellung nullobj . Siehe das Protokoll unten (wobei $
die Eingabeaufforderung für die Bash-Anweisung steht):
$ shopt -p | grep nullglob shopt -u nullglob $ shopt -s nullglob $ shopt -p | grep nullglob shopt -s nullglob
Die abschließende Bash-Syntax, mit der null oder mehr Dateien behandelt werden, die einem Platzhaltermuster entsprechen, sieht also folgendermaßen aus:
#!/bin/bash SAVED_NULLGLOB=$(shopt -p | grep nullglob) shopt -s nullglob for f in *.ext; do handle "$f" done eval "$SAVED_NULLGLOB"
In der Frage wurden auch mehrere Muster genannt:
for f in *.ext1 special.ext1 *.ext2; do ...
Die Option nullglob wirkt sich nicht auf ein Wort in der Liste aus, bei dem es sich nicht um ein "Muster" handelt. Es wird also special.ext1
weiterhin an die Schleife übergeben. Die einzige Lösung für dieses ist @Gordon Davisson ‚s continue
Ausdruck [ -e "$f" ] || continue
.
Danksagung: Sowohl @Ignacio Vazquez-Abrams als auch @Gordon Davisson spielten auf bash(1)
seine Nullglob- Option an. Vielen Dank. Da sie nicht sofort mit einem ausführlichen Beispiel zur Antwort beigetragen haben, tue ich das selbst.