Ignora "nessuna corrispondenza"


8

Vorrei elencare tutti i file in una cartella chiamata foldernamecon estensione test, atestoppure btest.

Il mio pensiero immediato fu di scappare ls ./foldername/*.{a,b,}test

Funziona bene a meno che non ci sia nulla con l'estensione atest, nel qual caso ottengo l'errore zsh: no matches found: ./foldername/*.atest.

C'è un modo in cui posso semplicemente ignorare questo errore e stampare i file che esistono?

Ho bisogno di questo per funzionare sia in ZSH che in BASH.


3
Reindirizzare l'errore standard su /dev/null?
DopeGhoti,

Risposte:


9

Potrebbe essere meglio farlo con find:

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'

1
forse con un -maxdepth 1, per emulare più da vicino il lscomportamento
Jeff Schaller

4
@JeffSchaller, nota che -maxdepthè un'estensione GNU. Nota 3 altre differenze con globs: findincluderebbe i file nascosti, non ordinerebbe l'elenco e non corrisponderebbe ai nomi dei file che contengono byte che non formano caratteri validi (come un $'St\xe9phane.atest'in una locale UTF-8)
Stéphane Chazelas

11

In

ls -d ./foldername/*.{a,b,}test

{a,b,...} non è un operatore glob, questa è un'espansione di parentesi graffe, che per la prima volta viene espansa a:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

E ogni glob si espande individualmente e, se un glob non corrisponde, il comando viene annullato come ci si aspetterebbe zsh(o fish; in bash, è necessaria l' failglobopzione per ottenere un comportamento simile).

Qui, vorrai utilizzare un singolo glob che corrisponda a tutti quei file e annullare il comando solo se quel glob non corrisponde a nessun file:

ls -d ./foldername/*.(a|b|)test

Non si desidera utilizzare nullglob, come se nessuno dei globs corrispondesse, verrebbe eseguito lssenza argomenti, quindi elencare la directory corrente. cshnullglobè migliore a tale riguardo in quanto rimuove globi non corrispondenti ma annulla comunque il comando se tutti i globi non corrispondono.

Non vorrai usare nonomatch, poiché ciò ti darebbe il comportamento rotto di bashcui sarebbe un peccato.

Per un'alternativa glob che funziona in entrambi zshe bash, puoi usare i globs ksh ( set -o kshglobdentro zshe shopt -s extglobdentro bash).

Quindi, faresti:

ls -d ./foldername/*.@(a|b|)test

o:

ls -d ./foldername/*.?([ab])test

Aggiungi l' failglobopzione bashper evitare che il glob venga passato letteralmente a lsquando non corrisponde.

Vedi Perché nullglob non è predefinito? per maggiori informazioni.


Non sono sicuro del motivo per cui è un requisito dell'OP, ma esiste un extglob che funziona sia in bash che in zsh? Ho dovuto usare ?(...)o +(...)per bash.
Jeff Schaller

@JeffSchaller, vedi modifica
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.