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 -nOder 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 vonnomatchvon 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
mmausgeben zweimal. -
In bash könnte man ein ähnliches Ergebnis wie in zsh erhalten, wenn die Shell-Option
failglobgesetzt ist:$ bash -c 'shopt -s failglob; echo ?m m?' bash: no match: ?mAber 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
nullglobsetzen 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: hjkVerwenden Sie besser
-dmitls(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
lswird einen Fehler melden$ ls ?m m? ls: cannot access '?m': No such file or directoryAndere Programme tun dies (wahrscheinlich) nicht führen Sie ähnliche Überprüfungen durch.
-
Mit
nullglobwith bash gibt ls eine leere Liste, also listet es den Inhalt oder das pwd auf, als ob es nurlswäre wurde ausgeführt:$ ls ?m m? ac a.out cz 3 b sc ab bcDies 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