Tengo una colección de archivos (* .zip, * .txt, * .tar.gz, * .doc, ... etc.). Estos archivos residen dentro de una ruta. Quiero encontrar todos los archivos (* .txt), luego copiar, solo, los archivos de texto que contienen palabras específicas (por ejemplo, LINUX / UNIX).
Ejecuté lo siguiente:
find . -name "*.txt" | grep 'LINUX/UNIX'
Este comando fue capaz de encontrar todos los archivos de texto, luego "grep" filtró los archivos de texto resultantes al enumerar solo los archivos de texto que contienen 'LINUX / UNIX'.
¿Cómo puedo copiar estos archivos finales (es decir, los archivos de texto que contienen 'LINUX / UNIX') a una ruta específica de elección?
Traté de aplicar xargs
find . -name "*.txt" | grep 'LINUX/UNIX' | xargs cp <to a path>
Pero no funcionó
Respuestas:
Tratar:
Debido a que este comando usa separación NUL, es seguro para todos los nombres de archivos, incluidos aquellos con nombres difíciles que incluyen espacios en blanco, pestañas o incluso nuevas líneas.
Lo anterior requiere GNU
cp
. Para MacOS / FreeBSD, intente:Cómo funciona:
grep
opciones y argumentos-r
le dice a grep que busque recursivamente a través de la estructura de directorios. (En FreeBSD,-r
seguirá los enlaces simbólicos en los directorios. Esto no se aplica ni a OS / X ni a las versiones recientes de GNUgrep
).--include '*.txt'
le dice a grep que solo devuelva archivos cuyos nombres coincidan con el glob*.txt
(incluidos los ocultos como.foo.txt
o.txt
).-l
le dice a grep que solo devuelva los nombres de los archivos coincidentes, no la coincidencia misma.--null
le dice a grep que use caracteres NUL para separar los nombres de los archivos. (--null
es compatiblegrep
con GNU / Linux , MacOS y FreeBSD pero no con OpenBSD ).LINUX/UNIX
le dice a grep que busque solo archivos cuyo contenido incluya la expresión regularLINUX/UNIX
.
buscar en el directorio actual. Puede omitirlo en versiones recientes de GNUgrep
, pero luego necesitaría pasar un--
terminador de opcióncp
para protegerse contra los nombres de archivo que comienzan con-
.xargs
opciones y argumentos-0
le dice a xargs que espere una entrada separada por NUL.-r
le dice a xargs que no ejecute el comando a menos que se encuentre al menos un archivo. (Esta opción no es necesaria ni en BSD ni en OSX y no es compatible con OSXxargs
).cp -t /path/to/dest
copia los directorios al directorio de destino. (-t
requiere GNUcp
)fuente
cp -t
es solo para Linux.--null
y agregué una versión para BSD / OSX que no usacp -t
.grep
no tiene--null
.--null
.Más portátil (solo características POSIX):
fuente
El siguiente sh / Bash one liner es otro método, aunque solo funcionará en el directorio actual y no se repite:
La
-l
opción de grep imprimirá una lista de los archivos que se están copiando, aunque podría usarlos-q
si no desea ver nada en la pantalla.fuente
No estoy seguro de por qué la cadena original no funcionó. El siguiente comando funciona para mí.
find / -name (nombre de archivo *) | grep '(nombre de archivo.extención)' | xargs cp -t ./
En mi caso, filename * es una colección de archivos con el mismo nombre con diferentes tipos de archivos (txt, zip, etc.). Hago grep para encontrar solo filename.txt y copiarlo en mi directorio de destino (que es actualmente, ./).
fuente