410 Stimmen

Prüfen, ob eine Datei mit einem Platzhalter in einem Shell-Skript existiert

Ich versuche zu prüfen, ob eine Datei existiert, aber mit einem Platzhalter. Hier ist mein Beispiel:

if [ -f "xorg-x11-fonts*" ]; then
    printf "BLAH"
fi

Ich habe es auch ohne die Anführungszeichen versucht.

629voto

Costi Ciudatu Punkte 35188

Für Bash-Skripte ist der direkteste und leistungsfähigste Ansatz:

if compgen -G "${PROJECT_DIR}/*.png" > /dev/null; then
    echo "pattern exists!"
fi

Dies funktioniert selbst in Verzeichnissen mit Millionen von Dateien sehr schnell und erfordert keine neue Subshell.

Source


Am einfachsten ist es, sich auf ls Rückgabewert (es wird ein Wert ungleich Null zurückgegeben, wenn die Dateien nicht vorhanden sind):

if ls /path/to/your/files* 1> /dev/null 2>&1; then
    echo "files do exist"
else
    echo "files do not exist"
fi

Ich leitete die ls Ausgang, um ihn völlig geräuschlos zu machen.


Hier ist eine Optimierung, die sich ebenfalls auf die Glob-Expansion stützt, aber die Verwendung von ls :

for f in /path/to/your/files*; do

    ## Check if the glob gets expanded to existing files.
    ## If not, f here will be exactly the pattern above
    ## and the exists test will evaluate to false.
    [ -e "$f" ] && echo "files do exist" || echo "files do not exist"

    ## This is all we needed to know, so we can break after the first iteration
    break
done

Dies ist sehr ähnlich wie Antwort von grok12 aber es vermeidet die unnötige Iteration durch die gesamte Liste.

85voto

flabdablet Punkte 3255

Wenn Ihre Shell eine Nullglobus aktiviert ist, wird ein Platzhaltermuster, das auf keine Dateien passt, vollständig aus der Befehlszeile entfernt. Dadurch wird ls keine Pfadnamenargumente sehen, den Inhalt des aktuellen Verzeichnisses auflisten und erfolgreich sein, was falsch ist. GNU stat , das immer fehlschlägt, wenn keine Argumente oder ein Argument mit dem Namen einer nicht existierenden Datei angegeben werden, wäre robuster. Außerdem ist der &> Umleitungsoperator ein Bashismus.

if stat --printf='' /path/to/your/files* 2>/dev/null
then
    echo found
else
    echo not found
fi

Noch besser ist GNU finden. die eine Wildcard-Suche intern abwickeln und beenden kann, sobald sie eine passende Datei gefunden hat, anstatt Zeit mit der Abarbeitung einer möglicherweise riesigen Liste von Dateien zu verschwenden, die von der Shell erweitert wurden; dies vermeidet auch das Risiko, dass die Shell ihren Kommandozeilenpuffer überlaufen lässt.

if test -n "$(find /dir/to/search -maxdepth 1 -name 'files*' -print -quit)"
then
    echo found
else
    echo not found
fi

Nicht-GNU-Versionen von finden. möglicherweise nicht über die -max Tiefe Option, die hier verwendet wird, um die finden. suchen nur die /dir/to/search statt des gesamten Verzeichnisbaums, der dort verwurzelt ist.

42voto

Pankaj Parashar Punkte 8889

使用する。

files=(xorg-x11-fonts*)

if [ -e "${files[0]}" ];
then
    printf "BLAH"
fi

35voto

joseyluis Punkte 517

Sie können Folgendes tun:

set -- xorg-x11-fonts*
if [ -f "$1" ]; then
    printf "BLAH"
fi

Dies funktioniert mit sh und Derivaten: KornShell und Bash. Es wird keine Sub-Shell erstellt. Die Befehle $(..) und `...`, die in anderen Lösungen verwendet werden, erzeugen eine Sub-Shell: sie spalten einen Prozess auf und sind ineffizient. Natürlich funktioniert es mit mehreren Dateien, und diese Lösung kann die schnellste oder die zweitschnellste sein.

Es funktioniert auch, wenn es keine Übereinstimmungen gibt. Es ist nicht nötig, nullglob zu verwenden, wie einer der Kommentatoren sagt. $1 wird den ursprünglichen Testnamen enthalten, und daher wird der Test -f $1 nicht erfolgreich sein, weil die Datei $1 nicht existiert.

26voto

grok12 Punkte 3336
for i in xorg-x11-fonts*; do
  if [ -f "$i" ]; then printf "BLAH"; fi
done

Dies funktioniert mit mehreren Dateien und mit Leerzeichen in Dateinamen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X