Estoy interesado en buscar de forma recursiva una cadena en un directorio para un patrón y luego enviar el archivo coincidente a un directorio de destino. Pensé que podría hacer algo como lo siguiente, pero no parece tener sentido con la herramienta de búsqueda de Linux:
find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir
¿Existe una mejor manera de hacer esto? O una forma que incluso funcione sería un comienzo sólido.
Respuesta1
Hazlo man xargs
y mira la -I
bandera.
find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/
Además, find
espera un \;
o +
después de la -exec
bandera.
Respuesta2
No creo que necesites encontrarlo. grep recursivo:
grep -rl "MY PATTERN" .
Respuesta3
xargs
lee su entrada estándar y la coloca al final del comando que se ejecutará. Tal como lo has escrito, terminarías ejecutando
cp /dest/dir sourcefile1 sourcefile2 sourcefile3
que está al revés de lo que quieres.
Podrías usar la -I
opción para especificar un marcador de posición para xargs
, como este: xargs -I '{}' cp '{}' /dest/dir
.
Además, find
se encarga de la recursividad, por lo que grep
no es necesario -R
.
Solución final:
find . -type f -exec grep -il "MY PATTERN" '{}' + | xargs -I '{}' cp '{}' /dest/dir
Respuesta4
Ninguno de los ejemplos anteriores tiene en cuenta la posibilidad de que grep
's -l
genere resultados duplicados (archivos con el mismo nombre, pero en diferentes lugares) y, por lo tanto, el gancho find
de ' exec
s sobrescriba los archivos en el directorio de destino.
Un intento de resolver esto:
$ tree foo
foo
├── bar
│ ├── baz
│ │ └── file
│ └── file
├── destdir
└── file
3 directories, 3 files
$ while read a; do mv $a foo/destdir/$(basename $a).$RANDOM; done < <(grep -rl content foo)
$ tree foo
foo
├── bar
│ └── baz
└── destdir
├── file.10171
├── file.10842
└── file.25404
3 directories, 3 files