Sebbene l'uso del find
comando possa essere utile qui, la shell stessa offre opzioni per raggiungere questo requisito senza strumenti di terze parti. La bash
shell fornisce un'opzione di supporto globale estesa mediante la quale è possibile ottenere i nomi dei file in percorsi ricorsivi che corrispondono alle estensioni desiderate.
L'opzione estesa è quella extglob
che deve essere impostata usando l' shopt
opzione come di seguito. Le opzioni sono abilitate con il -s
supporto e disabilitate con lui -u
flag. Inoltre, è possibile utilizzare un paio di opzioni in più, ad esempio nullglob
in cui un globo senza pari viene completamente spazzato via, sostituito da un insieme di zero parole. E globstar
ciò consente di ricorrere in tutte le directory
shopt -s extglob nullglob globstar
Ora tutto ciò che devi fare è formare l'espressione glob per includere i file di una determinata estensione che puoi fare come di seguito. Usiamo un array per popolare i risultati glob perché, se quotati correttamente ed espansi, i nomi dei file con caratteri speciali rimarrebbero intatti e non si spezzerebbero a causa della divisione delle parole da parte della shell.
Ad esempio, per elencare tutti i *.csv
file nei percorsi ricorsivi
fileList=(**/*.csv)
L'opzione **
è ricorrere attraverso le sottocartelle ed *.csv
è l'espansione glob per includere qualsiasi file delle estensioni menzionate. Ora per stampare i file effettivi, basta
printf '%s\n' "${fileList[@]}"
L'uso di un array e l'esecuzione di una corretta espansione quotata è il modo giusto se utilizzato negli script di shell, ma per un uso interattivo, si può semplicemente usare ls
con l'espressione glob come
ls -1 -- **/*.csv
Questo potrebbe benissimo essere espanso per abbinare più file, ad esempio il file che termina con più estensioni (cioè simile all'aggiunta di più flag nel find
comando). Ad esempio, considera un caso di necessità di ottenere tutti i file di immagine ricorsivi, ad esempio delle estensioni *.gif
, *.png
e *.jpg
tutto ciò che devi fare è
ls -1 -- **/+(*.jpg|*.gif|*.png)
Questo potrebbe benissimo essere ampliato per avere anche risultati negativi. Con la stessa sintassi, si potrebbero usare i risultati del glob per escludere file di un certo tipo. Supponi di voler escludere i nomi dei file con le estensioni sopra, puoi farlo
excludeResults=()
excludeResults=(**/!(*.jpg|*.gif|*.png))
printf '%s\n' "${excludeResults[@]}"
Il costrutto !()
è un'operazione negativa per non includere nessuna delle estensioni di file elencate all'interno ed |
è un operatore di alternanza proprio come usato nella libreria Extended Regular Expressions per eseguire una corrispondenza OR dei globs.
Si noti che questo supporto globale esteso non è disponibile nella shell bourne POSIX ed è puramente specifico per le versioni recenti di bash
. Quindi se stai considerando la portabilità degli script in esecuzione su POSIX e bash
shell, questa opzione non sarebbe corretta.