unix - salir - como utilizar el comando cat
Cómo pasar la lista de archivos devueltos por el comando find a cat para ver todos los archivos (14)
Estoy haciendo un find
y luego obtengo una lista de archivos. ¿Cómo lo canalizo a otra utilidad como cat
(para que cat muestre el contenido de todos esos archivos) y básicamente necesito grep
algo de estos archivos?
Canalizando a otro proceso (aunque esto NO LOGRARá lo que dijiste que estás tratando de hacer):
command1 | command2
Esto enviará la salida de command1 como la entrada de command2
-exec
en unfind
(esto hará lo que quiera hacer, pero es específico parafind
)find . -name ''*.foo'' -exec cat {} /;
(Todo entre
find
y-exec
son los predicados de búsqueda que ya-exec
.{}
Sustituirá el archivo particular que encontraste en el comando (cat {}
en este caso); el/;
es para finalizar el comando-exec
).enviar salida de un proceso como argumentos de línea de comando a otro proceso
command2 `command1`
por ejemplo:
cat `find . -name ''*.foo'' -print`
(Tenga en cuenta que estas son COPIAS ATRÁS no citas regulares (bajo la tilde ~ en mi teclado).) Esto enviará la salida de
command1
acommand2
como argumentos de línea de comando. Sin embargo, tenga en cuenta que los nombres de archivo que contienen espacios (líneas nuevas, etc.) se dividirán en argumentos separados.
¿Estás tratando de encontrar texto en los archivos? Simplemente puede usar grep para eso ...
grep searchterm *
Aquí está mi foto para uso general:
grep YOURSTRING `find .`
Imprimirá el nombre del archivo
El comando find tiene un argumento -exec que puedes usar para cosas como esta, puedes hacer el grep directamente usando eso.
Por ejemplo ( de aquí, otros buenos ejemplos en esta página ):
find . -exec grep "www.athabasca" ''{}'' /; -print
En bash, lo siguiente sería apropiado:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Esto encontrará todos los archivos en el directorio /dir
, y canalizará los nombres de archivo de manera segura a xargs
, lo que conducirá de manera segura a grep
.
Saltarse xargs
no es una buena idea si tiene muchos miles de archivos en /dir
; cat
se romperá debido a la longitud excesiva de la lista de argumentos. xargs
lo resolverá todo por ti.
El argumento -print0
para find
mallas con el argumento -0
a xargs
para manejar nombres de archivos con espacios correctamente. El argumento -i
para xargs
permite insertar el nombre de archivo donde se requiera en la línea de comando cat
. Los corchetes se reemplazan por el nombre de archivo canalizado en el comando cat
de find
.
Esta es mi manera de encontrar nombres de archivos que contengan algún contenido que me interese, solo una línea de bash que también maneja espacios en nombres de archivo:
find . -name /*.xml | while read i; do grep ''<?xml'' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
Esto funciona para mí
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Hay algunas maneras de pasar la lista de archivos devueltos por el comando find
comando cat
, aunque técnicamente no todos utilizan tuberías, y ninguno realmente canaliza directamente a cat
.
Lo más simple es usar palos de retroceso:
cat `find [whatever]`
De manera equivalente, uno puede usar
$()
lugar de barras invertidas en algunos shells, incluidobash
:cat $(find [whatever])
Esto es menos portátil, pero es encajable.
Ambas sintaxis toman el resultado de
find
y lo ponen en la línea de comando decat
. Esto no funciona bien si el resultado tiene demasiada salida (más de lo que cabe en una línea de comandos) o si el resultado tiene caracteres especiales (como espacios).Puede usar la acción
-exec
s-exec
, que ejecuta un comando para cada archivo que encuentra:find [whatever] -exec cat {} /;
Esto ejecutará
cat
una vez por cada archivo en lugar de ejecutar una sola instancia decat
pasándole múltiples nombres de archivo que pueden ser ineficientes y pueden no tener el comportamiento que desea para algunos comandos (aunque está bien paracat
). La sintaxis también es incómoda de escribir; necesitas escapar del punto y coma porque el punto y coma es especial para el intérprete de comandos.Algunas versiones de
find
(más notablemente, la versión de GNU) te permiten reemplazar;
con+
para usar el modo de agregar defind
para ejecutar menos instancias decat
.find [whatever] -exec cat {} +
Esto pasará múltiples nombres de archivo a cada invocación de
cat
, que puede ser más eficiente. Sin embargo, tenga en cuenta que no se garantiza el uso de una sola invocación. Si la línea de comando sería demasiado larga, los argumentos se distribuyen en múltiples invocaciones decat
. Paracat
esto probablemente no es un gran problema, pero para algunos otros comandos esto puede cambiar el comportamiento de formas no deseadas. En los sistemas Linux, el límite de longitud de línea de comando es bastante grande, por lo que dividirse en múltiples invocaciones es bastante raro en comparación con otros sistemas operativos.El enfoque clásico / portátil es usar
xargs
:find [whatever] | xargs cat
xargs
ejecuta el comando especificado (cat
, en este caso) y agrega argumentos basados en lo que lee de stdin. Al igual que-exec
con+
, esto-exec
la línea de comandos si es necesario. Es decir, sifind
produce demasiada salida, se ejecutarácat
varias veces. Como se menciona en la sección sobre-exec
anterior, hay algunos comandos donde esta división puede dar como resultado un comportamiento diferente. Tenga en cuenta que el uso dexargs
como este tiene problemas con los espacios en los nombres de los archivos, ya quexargs
solo usa espacios en blanco como un delimitador.El método más robusto, portátil y eficiente también usa
xargs
:find [whatever] -print0 | xargs -0 cat
El
-print0
indica afind
que use delimitadores/0
(carácter nulo) entre nombres de archivo, y el-0
indica axargs
que espere estos/0
delimitadores. Esto tiene un comportamiento prácticamente idéntico al enfoque-exec
...+
, aunque es más portátil (pero desafortunadamente más prolijo).
Para lograr esto (usando bash) haría lo siguiente:
cat $(find . -name ''*.foo'')
Esto se conoce como la "sustitución de comando" y elimina el avance de línea por defecto, ¡lo cual es realmente conveniente!
más información here
Para mostrar y ver el contenido de todos los archivos abc.def en un servidor en los directorios / ghi y / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} /; -exec cat {} /;
Para listar los archivos abc.def que tienen entradas comentadas y mostrar, vea esas entradas en los directorios / ghi y / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} /;
Suena como un trabajo para un guión de shell para mí:
for file in ''find -name *.xml''
do
grep ''hello'' file
done
o algo así
Use ggrep .
ggrep -H -R -I "mysearchstring" *
buscar un archivo en Unix que contenga texto ubicado en el directorio actual o en un subdirectorio
Yo uso algo como esto:
find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>
-print0
argumento " -print0
" para el argumento "buscar" y " -0
" para "xargs" es necesario para manejar correctamente el espacio en blanco en las rutas / nombres de archivo.
find . -print | xargs grep something
Si está en Linux o tiene el GNU find
y xargs
, use -print0
con find
y -0
con xargs
para manejar nombres de archivos que contengan espacios y otros caracteres de bolas impares.
Si no desea los nombres de los archivos, solo el texto, agregue una opción apropiada para grep
(usualmente -h
para suprimir ''encabezados''). Para garantizar que grep
imprima el nombre del archivo (incluso si solo se encuentra un archivo, o la última invocación de grep
solo tiene 1 nombre de archivo), agregue /dev/null
a la línea de comando de xargs
, para que siempre haya ser al menos dos nombres de archivo.
Tenga en cuenta que POSIX 2008 agregó el marcador +
para find
que significa que ahora agrupa automáticamente tantos archivos como sea razonable en una sola ejecución de comandos, muy parecido a lo que hace xargs
, pero con una serie de ventajas:
- No tiene que preocuparse por caracteres extraños en los nombres de archivo.
- No tiene que preocuparse por el comando que se invoca con cero nombres de archivo.
Ambos son problemas con xargs
sin la opción -0
. Por lo tanto, puedes escribir sensiblemente:
find . -exec grep something {} +