Pomocí bash nastavte nastavení glob tak, aby chybějící shody nezpůsobily chybu:
shopt -u failglob # avoid failure report (and discarding the whole line).
shopt -s nullglob # remove (erase) non-matching globs.
ls ?c c?
Otazník je znak glob představující jeden znak. Protože chcete dvouznakové názvy souborů, jeden z nich musí být c , a je to buď první znak, nebo poslední znak.
S shopt -s dotglob tím by se také objevil soubor s názvem .c .
Pokud neexistují žádné odpovídající soubory, nastavení těchto možností shellu způsobí odstranění všech argumentů, což má za následek holý ls -- výchozí seznam čehokoli/všeho.
Místo toho použijte toto:
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
Myslím, že lepší způsob je použít find :
find . -type f -name '*c*' -name '??'
To bude hledat rekurzivně. Chcete-li zobrazit pouze soubory v aktuálním adresáři:
find . ! -name . -prune -type f -name '*c*' -name '??'
Pokud soubory existují (a neobsahují žádné speciální znaky jako \c ), můžete použít glob:
echo ?c c?
které budou odpovídat souborům, které mají jeden znak (? ) následovaný c nebo které mají c následovaný jedním znakem (? ).
Ale selže s názvy souborů které začínají pomlčkou jako -n nebo -e nebo se znaky zpětného lomítka jako \c nebo \n s echo jako oba -e a -n jsou speciální pro (některé shelly) echo a \c nebo \n by bylo interpretováno jako escape sekvence (\c ukončí výstup a \n vytiskne nový řádek, nikoli doslovné znaky \n v nějaké implementaci shellu echo a bash, když je volba shopt -s xpg_echo je nastaveno). Jiné aplikace nebo nástroje (jako ls ) bude mít některé další možnosti a může selhat u mnoha dalších spouštěných pomlčkou nebo interpretovat jiné znaky escape v názvech souborů.
Zobrazí také soubor s názvem cc dvakrát.
-
Pokud soubor může začínat pomlčkou (např. -n), použijte:
$ ls -d -- ?n -nNebo lépe:
$ ls -d ./?n ./-n
Upozornění
-
Glob neodpovídá žádný soubor.
-
Pokud soubory neexistují, globus nebude rozbalen a glob bude vytištěn v původní podobě.
$ echo ?m m? ?m m? -
Kromě zsh.
$ zsh -c 'echo ?m m?' zsh:1: no matches found: ./m?Shell se ukončí s chybou.
Toto chování je řízenonomatchZsh možnost.$ zsh -c 'setopt +o nomatch; echo ?m m?' ?m m?Nebo:
$ zsh -c 'echo ?m(N) m?(N)' ?m m?Ale to vypíše
mmdvakrát. -
V bash můžete získat podobný výsledek jako zsh, pokud použijete volbu shellu
failglobje nastaveno:$ bash -c 'shopt -s failglob; echo ?m m?' bash: no match: ?mAle skript se nezastaví, shell se neukončí. Technicky vzato, řádek, kde se používá glob, se dále nespouští, ale provádění pokračuje na dalším řádku skriptu.
-
V bash můžete nastavit volbu
nullglobpro odstranění globů, které se neshodují:$ bash -c 'shopt -s nullglob; echo ?m m? done' done
-
-
Použití ls (podobně jako u jiných programů)
-
S odpovídajícími soubory nebude žádný problém, ale bude také odpovídat (a vypíše) adresáře:
$ ls ?c c? bc cz sc ac: hjkRaději použijte
-dsls(adresáře budou zahrnuty, ale nebudou rozšířeny).$ ls -d ?c c? ac bc cz sc -
Globy neodpovídají souboru (nebo adresáři)
Poté
lsohlásí poruchu$ ls ?m m? ls: cannot access '?m': No such file or directoryJiné programy možná (pravděpodobně) ne proveďte podobné kontroly.
-
Pomocí
nullglobs bash dá prázdný seznam ls, takže vypíše obsah nebo pwd, jako by jenlsbyl proveden:$ ls ?m m? ac a.out cz 3 b sc ab bcTomu by se dalo předejít pomocí
./$ ls -d ./?m ./m? ls: cannot access './?m': No such file or directory ls: cannot access './m?': No such file or directory
-
Nebo můžete použít regex find (ale bude procházet podadresáře s prune chybí) (Upozorňujeme, že toto nebude opakovat soubor s názvem cc):
$ find . ! -name . -prune -regex '.*/\(.c\|c.\)'
./ac
./cc
./sc
./bc
./cz