Tengo un directorio con cca 26 000 archivos y necesito grep en todos estos archivos. El problema es que lo necesito lo más rápido posible, por lo que no es ideal hacer un script donde grep tome el nombre de un archivo del comando find y escriba coincidencias en el archivo. Antes del problema "la lista de argumentos es demasiado larga", tomó aproximadamente 2 minutos para grep en todos estos archivos. ¿Alguna idea de como hacerlo? editar: hay un script que está creando nuevos archivos todo el tiempo, por lo que no es posible poner todos los archivos en diferentes directorios.
files
grep
performance
usuario2778979
fuente
fuente
find
conxargs
ogrep -R
Respuestas:
Con
find
:(
-type f
es buscar solo en archivos normales (también excluyendo enlaces simbólicos incluso si apuntan a archivos normales). Si desea buscar en cualquier tipo de archivo excepto directorios (pero tenga cuidado, hay algunos tipos de archivos como fifos o / dev / zero que generalmente no desea leer), reemplace-type f
con el específico de GNU! -xtype d
(-xtype d
coincidencias para archivos de tipo directorio después de la resolución del enlace simbólico)).Con GNU
grep
:(pero tenga en cuenta que a menos que tenga una versión reciente de GNU grep, seguirá los enlaces simbólicos cuando descienda a los directorios). No se buscarán archivos no regulares a menos que agregue una
-D read
opción. Singrep
embargo, las versiones recientes de GNU aún no buscarán dentro de enlaces simbólicos.Las versiones muy antiguas de GNU
find
no admitían la{} +
sintaxis estándar , pero allí podría usar la no estándar:Es probable que las actuaciones estén vinculadas a E / S. Ese es el momento de hacer la búsqueda, sería el tiempo necesario para leer todos esos datos del almacenamiento.
Si los datos están en una matriz de discos redundante, leer varios archivos a la vez podría mejorar el rendimiento (y de lo contrario podría degradarlos). Si los rendimientos no están vinculados a E / S (porque, por ejemplo, todos los datos están en caché), y tiene varias CPU, la concurrencia también
greps
podría ayudar. Puede hacerlo conxargs
la-P
opción de GNU .Por ejemplo, si los datos están en una matriz RAID1 con 3 unidades, o si los datos están en caché y tiene 3 CPU cuyo tiempo de sobra:
(aquí se usa
-n1000
para generar un nuevogrep
cada 1000 archivos, hasta 3 que se ejecutan en paralelo a la vez).Sin embargo, tenga en cuenta que si la salida de
grep
se redirige, terminará con una salida mal entrelazada de los 3grep
procesos, en cuyo caso es posible que desee ejecutarlo como:(en un sistema GNU o FreeBSD reciente) o use la
--line-buffered
opción de GNUgrep
.Si
pattern
es una cadena fija, agregar la-F
opción podría mejorar las cosas.Si no se trata de datos de caracteres de varios bytes, o si coincide con ese patrón, no importa si los datos son de caracteres de varios bytes o no, entonces:
podría mejorar el rendimiento significativamente.
Si terminas haciendo tales búsquedas con frecuencia, entonces puedes querer indexar tus datos usando uno de los muchos motores de búsqueda disponibles.
fuente
26000 archivos en un solo directorio es mucho para la mayoría de los sistemas de archivos. Es probable que se tome una parte importante del tiempo leyendo este gran directorio. Considere dividirlo en directorios más pequeños con solo unos pocos cientos de archivos cada uno.
Llamar
find
no puede explicar el bajo rendimiento a menos que lo hagas mal. Es una forma rápida de atravesar un directorio y de garantizar que no se arriesgue a intentar ejecutar una línea de comando que sea demasiado larga. Asegúrese de usar-exec grep PATTERN {} +
, que empaqueta tantos archivos como sea posible por invocación de comando, y no-exec grep PATTERN {} \;
, que se ejecutagrep
una vez por archivo: es probable que la ejecución del comando una vez por archivo sea significativamente más lenta.fuente
Si necesita agrupar TODOS los archivos varias veces (como dijo, ejecutando un script), le sugiero que busque en los discos RAM, copie todos los archivos allí y luego agrupe los archivos varias veces, esto acelerará su búsqueda por un factor de al menos 100x.
Solo necesitas suficiente carnero. De lo contrario, debe buscar indexar los archivos, por ejemplo. en lucene o en una base de datos nosql y luego ejecuta consultas sobre eso.
fuente
grep
. También está el punto de que: "hay un script que está haciendo nuevos archivos todo el tiempo, por lo que no es posible poner todos los archivos en directorios diferentes".Todos los archivos en el directorio
con recursivamente
fuente
.
lugar de*
).*
excluirá los archivos de puntos (aunque con -R, no los que están en los directorios recurrentes). -R en oposición a -r sigue enlaces simbólicos incluso con versiones recientes de GNU grep. También tendrá un problema con los archivos en el directorio actual cuyo nombre comienza con-