Comando Grep para buscar archivos que contengan cadenas de texto y moverlos


15

Puedo ubicar archivos en una carpeta que contiene una cadena de texto específica usando este comando:

grep -lir 'string' ~/directory/*

¿Cómo muevo los archivos que aparecen en el resultado anterior a otra ubicación?


Aquí está. grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Alan Dong

Respuestas:


10

Como siempre, ten cuidado grep -r. -rno es una opción estándar, y en algunas implementaciones como todas las versiones de GNU grep, excepto las muy recientes , sigue enlaces simbólicos al descender el árbol de directorios, que generalmente no es lo que desea y puede tener graves consecuencias si, por ejemplo, hay un enlace simbólico a "/ "en algún lugar del árbol de directorios.

En la filosofía de Unix, utiliza un comando para buscar directorios en los archivos y otro para ver su contenido.

Usando herramientas GNU, haría:

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

Pero incluso entonces, tenga cuidado con las condiciones de carrera y los posibles problemas de seguridad si lo ejecuta como un usuario en un directorio que otro usuario puede escribir.


esto me da error find: 'grep' terminado por la señal 13. ¿alguna idea de qué va mal?
Reena Parekh

@ReenaParekh, eso sería un SIGPIPE. Eso solo sucedería si xargssale antes de leer hasta el final de su archivo arg, lo que no debería suceder a menos que xargs se mate o falle por algún motivo, en cuyo caso esperaría que también vea un error al respecto.
Stéphane Chazelas

15

Usar xargsen concierto con mvla tercera sintaxis de:mv [OPTION]... -t DIRECTORY SOURCE...

grep -lir 'string' ~/directory/* | xargs mv -t DEST

Tenga cuidado con los archivos que contienen caracteres especiales (espacios, comillas). Si este es su caso, puede ser útil filtrar la lista con sed(agregando comillas alrededor de los nombres de archivo con s/^/'/;s/$/'/), pero debe asegurarse, estas comillas no aparecerán en los nombres de archivo. GNU greptiene la opción -Z/ --nullpara terminar nombres de archivo NUL.

Una alternativa a la tercera sintaxis mves usar xargscon la cadena de marcador de posición ( -I).

Otra opción es la sustitución de comandos $( )o backticks ``(en bash) como se menciona en la respuesta de ire_and_curses.


3
gnu grep admite una bandera -Z para separar los nombres de archivo por el carácter de cero bytes, que cuando se usa junto con la bandera -0 para xargs, puede evitar el problema de caracteres especiales que mencionas
iruvar el

@ChandraRavoori gracias, he actualizado la respuesta.
Peter


2

Usando solo las características especificadas de POSIX y sin hacer suposiciones sobre los nombres de archivo:

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

Notas:

Dijiste "cadena", no "patrón", por lo que la -Fopción (búsqueda de cadena fija) grepparece apropiada.

Si su directorio de destino está en algún lugar dentro de su directorio de búsqueda, puede tener algunas condiciones de carrera desagradables.

Especificaciones POSIX para grep

Especificaciones POSIX para find


Esta podría ser la mejor solución en Macos / BSD
Ali

0

Usando GNU paralelo :

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dong por su respuesta original con xargs.


Hubiera sido agradable si hubieras acreditado la respuesta de @ lindong en los comentarios de hace más de un año.
roaima el

0

-Suponga que tiene el directorio de destino como 'externo' y necesita mover todos los archivos XLS, puede probar el siguiente comando

sudo mv find /var/log/ -type f -name "*.xls"/ externo /

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.