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).