Su Linux, come posso trovare tutti i file che contengono una stringa ed eliminarli?


17

Voglio eliminare tutti i file che contengono la stringa foo. Come posso farlo usando bash in Linux?


quella stringa è il nome del suo file?
rʒɑdʒɑ

3
Si prega di chiarire: si desidera eliminare i file il cui nome contiene foo(ad es. myfoo.jpg) O file che contengono la sequenza di byte foo(che può includere file binari che a volte contengono quella sequenza di byte)?
Hammar,

Risposte:


33

Ecco un modo sicuro:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l stampa i nomi dei file corrispondenti al modello di ricerca.
  • -resegue una ricerca ricorsiva per il modello foonella directory specificata .. Se questo non funziona, prova -R.
  • -I(maiuscolo i) fa saltare i file binari come i PDF.
  • -Z assicura che i nomi dei file siano a zero (ovvero nul-) in modo che un nome contenente spazi bianchi non venga interpretato in modo errato (ovvero come nomi multipli anziché uno).
  • xargs -0alimenta i nomi dei file da grepa rm -f, separando le parole per zero (nul) byte (ricordare l' -Zopzione da grep).
  • -- viene spesso dimenticato, ma è molto importante contrassegnare la fine delle opzioni e consentire la rimozione di file i cui nomi iniziano con - .

Se si desidera vedere quali file stanno per essere eliminati, è sufficiente rimuovere la | xargs -0 rm -f --parte e lasciare l' Zopzione sugrep .

Un altro utente ha suggerito qualcosa di simile al seguente, che non dovresti eseguire perché non è sicuro:

files=`grep foo * | cut -d: -f1`
rm -f $files         # unsafe, do not run it!

Se ho file ImportantStuffche non voglio eliminare e che obsolete ImportantStuffcontengono foo, allora perdo ImportantStuff(e non obsolete ImportantStuff !) Quando eseguo questo comando, perché $filesviene spezzato negli spazi quando viene interpretato. In questo modo è pericoloso inserire un elenco di nomi di file in una variabile di shell scalare.


17
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;

Questo ricorsivamente cerca i file contenenti foo. Il secondo -execviene eseguito solo se il primo viene execchiuso correttamente, ovvero se grepcorrisponde. Asciugare e rimuovere ilecho se l'output sembra corretto.

O in alternativa

$ find -type f -exec grep -q "foo" {} \; -print

e

$ find -type f -exec grep -q "foo" {} \; -delete

come suggerito da Lekensteyn.


4
... che può essere abbreviato in: find -type f -exec grep -q 'foo' {} \; -delete(le virgolette intorno {}sono ridondanti, findè anche in grado di eliminare i file.). Nota che grepaccetta un'espressione regolare. Se si desidera cercare foo.bar, sfuggire a questo o passare l' -Fopzione per trattare il modello come letterale.
Lekensteyn,

qualche motivo per usare -exec echo rm "{}" \;e no -delete?
vartec,

1
@vartec No, lo userei -delete. È solo più facile dimostrarlo con il secondo -execed eco in atto.
Adrian Frühwirth,

1
È più facile da scrivere -print(o -lsper più verbosità) di -exec echo rm "{}" \'. Non sono necessarie utilità esterne.
Lekensteyn,

1
se usi rm {}, usa rm - {}, in modo che eventuali caratteri speciali nel nome del file stesso non vengano interpolati. Ad esempio, tocca '-rf /' in qualsiasi directory in cui hai i permessi di scrittura ...
atk

1

Farei quello che dice Adrian,

Ma aggiungerei i confini delle parole intorno al foo in modo da non cancellare accidentalmente i file contenenti "food" (a meno che non stia eliminando tutto ciò che contiene food è quello che vuoi.)

 $ find -type f -exec grep -q "\<foo\>" {} \; -delete

acutalmente, reindirizzerei l'output prima di eliminarlo in modo da poterlo rivedere prima di eliminare:

 $ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete

Non appena sei in grado di pubblicare commenti, dovresti pubblicare cose del genere come commenti.
FSMaxB,

sì, ho provato prima ma poi ho capito che non sono ancora autorizzato a pubblicare commenti.
Petter H
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.