Estoy tratando de ejecutar grep contra una lista de unos cientos de archivos:
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
Sin embargo, aunque estoy buscando una cadena que sé que se encuentra en los archivos, lo siguiente no busca los archivos:
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
Estoy familiarizado con la -fbandera que leerá los patrones de un archivo. Pero, ¿cómo leer los archivos de entrada ?
Había considerado la horrible solución de copiar los archivos a un directorio temporal, ya que cpparece admitir el <(cat files.txt)formato, y a partir de ahí agrupar los archivos. Shirley hay una mejor manera.
fuente

whilepodría recibir las líneas de file.txt como tal.whileno está recibiendo exactamente las líneas del archivo,readestá haciendo eso;whilesolo nos deja hacer eso en un bucle. El ciclo finaliza cuandoreadfalla (es decir, devuelve un código de retorno distinto de cero), normalmente debido a que se alcanza el Fin del archivo.IFS= read -r filename,read filenamees otra cosa.-Hes una extensión GNU. Te estás perdiendo un poco--.suponiendo que los archivos estén en blanco o delimitados por nueva línea (donde las comillas o barras invertidas pueden usarse para escapar de esos separadores). Con GNU
xargspuede especificar el delimitador con-d(que luego deshabilita el manejo de las comillas).suponiendo que los archivos estén separados por espacio, tabulación o nueva línea (no hay forma de escapar de ellos, aunque puede elegir un separador diferente asignándolo a
IFS). Ese fallará si la lista de archivos es demasiado grande en la mayoría de los sistemas.También se supone que ninguno de los archivos se llama
-.fuente
$(< file)lugar de$(cat file), al menos enbashyzsh.Para leer una lista de nombres de archivo de stdin puede usar
xargs. P.ej,Por defecto,
xargslee elementos de la entrada estándar, delimitados por espacios en blanco. El-d'\n'le dice que use nueva línea como delimitador de argumento, para que pueda manejar nombres de archivos que contienen espacios en blanco. (Como señala Stéphane Chazelas, esa es una extensión de GNU). Sin embargo, no hará frente a los nombres de archivo que contienen nuevas líneas; necesitaríamos un enfoque un poco más complicado para manejarlos.FWIW, este enfoque es algo más rápido que un
while readbucle, ya que elreadcomando de bash es muy lento: lee sus datos carácter por carácter, mientras quexargslee su entrada de manera más eficiente. Además,xargssolo invoca elgrepcomando tantas veces como sea necesario, con cada invocación recibiendo múltiples nombres de archivo, y eso es más eficiente que invocargrepindividualmente para cada nombre de archivo.Consulte la página de manual de xargs y la página de información de xargs para obtener más detalles.
fuente
xargspuede leer elementos de un archivo (como sufiles.txtlista) con su opción:Entonces esto también debería funcionar:
o para espacios en nombres de archivo
fuente
También puedes hacer un for pero el ejemplo de Orion es el más simple:
(Para cada archivo listado en files.txt, ejecute el comando grep en él).
fuente