Eliminar archivos sin cadena en el nombre

9

Quiero eliminar archivos que no tengan la cadena '999' (sin el '') en su nombre.

Yo he tratado:

grep -vlr 999 . | xargs -0 rm -f --
find . -print0 | grep --null-data -v 999 | xargs -0 rm --

Pero ninguno de ellos funciona. Estoy usando macOS Sierra, con bash: 3.2.57.

plr
fuente
2
grep -lhace que enumere los archivos donde se encontró una coincidencia (o no se encontró con -v) en el contenido , no el nombre de archivo. grepsiempre coincide con el contenido de los archivos que especifique, nunca sus nombres.
JoL

Respuestas:

18

Usando un patrón de globo extendido en bash:

rm ./!(*999*)

Esto requiere shopt -s extglobestar habilitado (y por seguridad, también shopt -s failglob, para que ningún archivo con el nombre inusual !(*999*)se elimine por error si todos los nombres de archivo contienen 999). El patrón !(*999*)coincidirá con cualquier nombre en el directorio actual, excepto aquellos nombres que coincidan *999*. Para eliminar también archivos ocultos (archivos cuyo nombre comienza con un punto ), habilite también la dotglobopción.

Para preocuparse solo por los archivos regulares o los enlaces simbólicos a los archivos regulares (no directorios, etc.):

for name in ./!(*999*); do [ -f "$name" ] && rm "$name"; done

El zshshell equivalente al bucle anterior sería

rm ./(^(*999*))(.)

Su primer comando no funcionará ya grepque buscará dentro de los archivos. Eliminaría todos los archivos que tienen líneas sin 999ellos (si hubiera agregado la --nullopción para que funcione xargs -0).

Su segundo comando no funcionará ya que grepen macOS no es compatible --null-data(sin embargo, tiene una --nullopción, pero solo para generar la salida del nombre de archivo). También tenga en cuenta que buscaría en 999cualquier lugar de la ruta del archivo (incluidos los componentes del directorio), no solo el nombre del archivo.

Kusalananda
fuente
1
También querrá habilitar la failglobopción o podría terminar eliminando el archivo llamado !(*999*)si no hay otro archivo cuyo nombre no contenga 999.
Stéphane Chazelas
16

Simplemente invierta la condición del nombre en find:

find . -type f \! -name "*999*" 

Agregar -deleteo -exec rm {} +para eliminar realmente los archivos coincidentes.

ilkkachu
fuente
2
!está a salvo en bash.
Kusalananda