Diciamo che ho una directory con più file, che sono tutti file binari (file senza estensione dichiarata) e file sorgente (.c
estensione). Faccio questo:
$ ls
e ottieni:
README.md hello-world.c hello-world get-name.c get-name
e voglio elencare solo i file con un'estensione specifica (diciamo entrambi .c
e .md
), lo faccio:
ls *.c *.md
e va bene!
Ma cosa succede se ora voglio eliminare tutti i file che non avere un .c
o .md
estensione, come posso farlo?
So come farlo su file le cui estensioni mi sono note, come:
ls *.c *.md | xargs rm
Ma come faccio a dire alla riga di comando di eliminare i file che NON corrispondono ai miei criteri?
Risposta accettata:
Usa find
:
find -maxdepth 1 ! -name "*.c" -print0 | xargs -0 ...
Nota che -maxdepth
, -print0
, -r
e -0
si trovano in alcuni find
implementazioni (sono state introdotte da GNU find
/xargs
) ma non sono specificati da POSIX. Un altro modo è, come ha detto Stéphane nel suo commento, usare il -exec
azione di ricerca:ricorda di utilizzare il comando -exec command {} +
form, poiché riduce drasticamente il numero di invocazioni di command
(deve consentire la sintassi in cui i nomi dei file sono posizionati alla fine, oppure è necessario eseguire il wrapping del command
all'interno di un sh -c
chiamare).
In alternativa grep
l'output di ls
ls | grep -v ".c$" | xargs ...
Puoi filtrare diverse estensioni sia con espressioni regolari:
... | grep -v ".(c|md)$" | ...
con espressioni regolari estese:
... | grep -Ev ".(c|md)$" | ...
con l'opzione di stringhe fisse (non corrisponderà solo alla fine del nome del file!):
... | grep -vF ".c
.md" | ...
o concatenando più grep
s:
... | grep -v ".c$" | grep -v ".md$" | ...
Detto questo, find
è probabilmente l'opzione migliore, poiché con -print0
opzione gestisce tutti i possibili caratteri nei nomi di file che potrebbero richiedere l'escape in caso contrario (a condizione che il tuo find
e xargs
sono in grado di lavorare con stringhe con terminazione NULL, ad es. gli strumenti GNU sono).