En Linux, ¿cómo puedo encontrar todos los archivos que contienen una cadena y eliminarlos?


17

Quiero eliminar todos los archivos que contienen la cadena foo. ¿Cómo puedo hacer esto usando bash en Linux?


esa cadena es su nombre de archivo?
— rɑːdʒɑ

3
Por favor aclare: ¿desea eliminar archivos cuyo nombre contiene foo(p myfoo.jpg. Ej. ) O archivos que contienen la secuencia de bytes foo(que pueden incluir archivos binarios que contienen esa secuencia de bytes)?
— hammar

Respuestas:


33

Aquí hay una manera segura:

grep -lrIZ foo . | xargs -0 rm -f --
  • -l imprime los nombres de los archivos que coinciden con el patrón de búsqueda.
  • -rrealiza una búsqueda recursiva del patrón fooen el directorio dado .. Si esto no funciona, inténtalo -R.
  • -I(capital i) hace que se omitan los archivos binarios como los PDF.
  • -Z garantiza que los nombres de los archivos estén terminados en cero (es decir, nul-) para que un nombre que contenga espacios en blanco no se interprete de manera incorrecta (es decir, como nombres múltiples en lugar de uno).
  • xargs -0alimenta los nombres de archivo de grepa rm -f, separando las palabras por cero (nul) bytes (recuerde la -Zopción de grep).
  • --a menudo se olvida, pero es muy importante marcar el final de las opciones y permitir la eliminación de archivos cuyos nombres comienzan con -.

Si desea ver qué archivos están a punto de eliminarse, simplemente elimine la | xargs -0 rm -f --pieza y desactive la Zopción grep.

Otro usuario sugirió algo como lo siguiente, que no debe ejecutar porque no es seguro:

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

Si tengo archivos ImportantStuffque no quiero eliminar y que obsolete ImportantStuffcontienen foo, entonces pierdo ImportantStuff(¡y no obsolete ImportantStuff !) Cuando ejecuto este comando, porque $filesse rompe en espacios cuando se interpreta. Es peligroso poner una lista de nombres de archivo en una variable de shell escalar de esta manera.


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

Esto busca de forma recursiva los archivos que contienen foo. El segundo -execsolo se ejecuta si el primero execsale con éxito, es decir, si grepcoincide. Ejecute en seco y elimine echosi la salida parece correcta.

O alternativamente

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

y

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

según lo sugerido por Lekensteyn.


44
... que se puede acortar a: find -type f -exec grep -q 'foo' {} \; -delete(las comillas {}son redundantes, findtambién puede eliminar archivos). Tenga en cuenta que grepacepta una expresión regular. Si desea buscar foo.bar, salga de esto o pase la -Fopción de tratar el patrón como literal.
— Lekensteyn

alguna razón para usar -exec echo rm "{}" \;y no -delete?
— vartec

1
@vartec No, lo usaría -delete. Es más fácil demostrar con el segundo -execy hacer eco en su lugar.
— Adrian Frühwirth

1
Es más fácil escribir -print(o -lspara más verbosidad) que -exec echo rm "{}" \'. No hay necesidad de utilidades externas.
— Lekensteyn

1
si usa rm {}, use rm - {}, para que los caracteres especiales en el nombre del archivo no se interpolen. Por ejemplo, toque '-rf /' en cualquier directorio donde tenga permisos de escritura ...
— atk

1

Haría lo que Adrian dice:

Pero agregaría límites de palabras al foo para no eliminar accidentalmente archivos que contengan "comida" (a menos que esté borrando todo lo que contiene comida es lo que desea).

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

agudamente, redirigiría la salida antes de eliminar para poder revisar antes de eliminar:

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

Tan pronto como pueda publicar comentarios, debe publicar cosas como esas como comentarios.
— FSMaxB

Sí, lo intenté primero pero luego me di cuenta de que todavía no tengo permitido publicar comentarios.
— Petter H
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.