Stellen Sie mit bash die Glob-Einstellungen so ein, dass fehlende Übereinstimmungen keinen Fehler auslösen:
shopt -u failglob # avoid failure report (and discarding the whole line).
shopt -s nullglob # remove (erase) non-matching globs.
ls ?c c?
Fragezeichen ist ein Glob-Zeichen, das ein einzelnes Zeichen darstellt. Da Sie zweistellige Dateinamen wünschen, muss einer davon ein c
sein , also entweder das erste oder das letzte Zeichen.
Mit shopt -s dotglob
dies würde auch eine Datei mit dem Namen .c
hervorbringen .
Wenn es keine übereinstimmenden Dateien gibt, führt das Setzen dieser Shell-Optionen dazu, dass alle Argumente entfernt werden, was zu einem bloßen ls
führt -- alles standardmäßig auflisten.
Verwenden Sie stattdessen Folgendes:
shopt -s nullglob ## drop any missing globs
set -- ?c c? ## populate the [email protected] array with (any) matches
if [ $# -gt 0 ] ## if there are some, list them
ls -d "[email protected]"
fi
Ich denke, der bessere Weg ist, find
zu verwenden :
find . -type f -name '*c*' -name '??'
Das wird rekursiv suchen. Um nur Dateien im aktuellen Verzeichnis aufzulisten:
find . ! -name . -prune -type f -name '*c*' -name '??'
Wenn die Dateien existieren (und keine Escape-Zeichen wie \c
), können Sie einen Glob verwenden:
echo ?c c?
das stimmt mit Dateien überein, die ein Zeichen haben (?
) gefolgt von einem c
oder die einen c
haben gefolgt von einem Zeichen (?
).
Wird aber bei Datei-Namen fehlschlagen die mit einem Bindestrich wie -n
beginnen oder -e
oder mit Backslash-Zeichen wie \c
oder \n
mit echo
als beide -e
und -n
sind speziell für (einige Muscheln) echo
und \c
oder \n
würde als Escape-Sequenz interpretiert (\c
beendet die Ausgabe und \n
gibt eine neue Zeile aus, nicht die wörtlichen Zeichen \n
in einigen Shell-Implementierungen von Echo und mit Bash, wenn die Option shopt -s xpg_echo
eingestellt ist). Andere Anwendungen oder Dienstprogramme (wie ls
) wird einige andere Optionen haben und kann mit vielen anderen Bindestrichen fehlschlagen oder andere Escape-Zeichen in Dateinamen interpretieren.
Wird auch eine Datei namens cc
auflisten zweimal.
-
Wenn eine Datei möglicherweise mit einem Bindestrich (wie -n) beginnt, verwenden Sie:
$ ls -d -- ?n -n
Oder besser:
$ ls -d ./?n ./-n
Warnhinweise
-
Glob passt keine Datei an.
-
Wenn die Dateien nicht existieren, wird der Glob nicht expandiert und der Glob wird in seiner ursprünglichen Form gedruckt.
$ echo ?m m? ?m m?
-
Außer in zsh.
$ zsh -c 'echo ?m m?' zsh:1: no matches found: ./m?
Die Shell wird mit einem Fehler beendet.
Dieses Verhalten wird vonnomatch
von Zsh gesteuert Option.$ zsh -c 'setopt +o nomatch; echo ?m m?' ?m m?
Oder:
$ zsh -c 'echo ?m(N) m?(N)' ?m m?
Aber das wird
mm
ausgeben zweimal. -
In bash könnte man ein ähnliches Ergebnis wie in zsh erhalten, wenn die Shell-Option
failglob
gesetzt ist:$ bash -c 'shopt -s failglob; echo ?m m?' bash: no match: ?m
Aber das Skript stoppt nicht, die Shell wird nicht beendet. Technisch gesehen wird die Zeile, in der der Glob verwendet wird, nicht weiter ausgeführt, sondern die Ausführung wird in der nächsten Skriptzeile fortgesetzt.
-
In der Bash könnte man die Option
nullglob
setzen So entfernen Sie nicht übereinstimmende Globs:$ bash -c 'shopt -s nullglob; echo ?m m? done' done
-
-
Verwendung von ls (ähnlich mit anderen Programmen)
-
Mit übereinstimmenden Dateien wird es kein Problem geben, aber es werden auch Verzeichnisse gefunden (und aufgelistet):
$ ls ?c c? bc cz sc ac: hjk
Verwenden Sie besser
-d
mitls
(Verzeichnisse werden eingeschlossen, aber nicht erweitert).$ ls -d ?c c? ac bc cz sc
-
Globs stimmen nicht mit einer Datei (oder einem Verzeichnis) überein
Dann
ls
wird einen Fehler melden$ ls ?m m? ls: cannot access '?m': No such file or directory
Andere Programme tun dies (wahrscheinlich) nicht führen Sie ähnliche Überprüfungen durch.
-
Mit
nullglob
with bash gibt ls eine leere Liste, also listet es den Inhalt oder das pwd auf, als ob es nurls
wäre wurde ausgeführt:$ ls ?m m? ac a.out cz 3 b sc ab bc
Dies könnte mit
./
vermieden werden$ ls -d ./?m ./m? ls: cannot access './?m': No such file or directory ls: cannot access './m?': No such file or directory
-
Oder Sie können einen Find-Regex verwenden (aber er durchsucht Unterverzeichnisse mit prune
fehlt) (Beachten Sie, dass dies eine Datei namens cc nicht wiederholt):
$ find . ! -name . -prune -regex '.*/\(.c\|c.\)'
./ac
./cc
./sc
./bc
./cz