Estoy usando egrep ( grep -E) con un archivo PATTERN. ( -f path/to/file)
Esto se realiza en un bucle infinito en una secuencia de texto. Esto implica que no puedo acumular y pasar TODA la entrada a grep a la vez (como *.log).
¿Hay alguna manera de hacer que grep "guarde" el NFA que está construyendo desde el archivo PATTERN para usarlo en su próxima ejecución?
He buscado en Google y he leído la documentación sin suerte.
Trataré de explicarlo un poco más. Necesito localizar un número fijo de cadenas con expresiones regulares (esto no es parte de una pregunta, pero siéntase libre de sugerir lo contrario) como direcciones IP, dominios, etc. La búsqueda se realiza en un feed de Internet. Puedes pensarlo como una secuencia de texto. No puedo usar greptodas las entradas ya que es una secuencia. Puedo acumular un fragmento de flujo y usarlo grep(por lo tanto, no usarlo grepen cada línea), pero esto también es limitado (digamos durante 30 segundos).
Sé que grepestá construyendo un NFA a partir de todos sus patrones (en mi caso a partir de un archivo). Entonces mi pregunta aquí es: ¿puedo decirle grepque guarde esa NFA para la próxima ejecución, ya que no va a cambiar? Eso me ahorraría el tiempo de construir esa NFA cada vez.

greppor línea de texto? ¿De dónde viene el texto? ¿tail -fSería una opción?grepesa parte.grepvarias veces. Posiblemente relacionado: ¿Por qué es tan lento hacer coincidir 1250 cadenas con patrones de 90k?grepestá destinado a funcionar en una secuencia de texto, todavía no entiendo por qué necesitarías ejecutar varias instancias. ¿Por qué no puedes alimentar a todos a la mismagrepinstancia? ¿Por qué necesitas acumularlos antes de alimentarlosgrep?Respuestas:
No, no hay tal cosa. En general, el costo de iniciar
grep(bifurcar un nuevo proceso, cargar el ejecutable, la biblioteca compartida, la vinculación dinámica ...) sería mucho mayor que compilar las expresiones regulares, por lo que este tipo de optimización tendría poco sentido.Sin embargo, vea ¿Por qué la coincidencia de 1250 cadenas con patrones de 90k es tan lenta? sobre un error en algunas versiones de GNU
grepque lo haría particularmente lento para una gran cantidad de expresiones regulares.Posiblemente aquí, podría evitar correr
grepvarias veces alimentando sus fragmentos a la mismagrepinstancia, por ejemplo, usándolo como un coproceso y use un marcador para detectar el final. Conzshy GNUgrepeawkimplementaciones que no seanmawk:Aunque puede ser más simple hacer todo con
awko en superllugar.Pero si no necesita la
grepsalida para ir a diferentes archivos para diferentes fragmentos, siempre puede hacer:fuente
greptal como está. Gracias.¿Eres consciente de que las tuberías se bloquean? Si conecta algo a grep y toda la entrada no está disponible, grep esperará hasta que esté disponible y luego continuará como si la entrada estuviera allí todo el tiempo.
EDITAR: cómo funcionan las canalizaciones, por ejemplo,
cmd1 | cmd2es que ambos programas se iniciarán al mismo tiempo, por ejemplo, con un "búfer de fragmentos" de 65.536 bytes entre ellos. Cuandocmd2intenta leer y ese búfer está vacío, esperará a que haya un fragmento disponible. Cuandocmd1intenta escribir y ese búfer está lleno, esperará hasta que locmd2lea.Por lo que puedo leer, no hay necesidad de cortar la entrada en trozos y pasarlos a grep por separado. Eso ya está hecho automáticamente.
EDIT2:
greptambién debe imprimir los resultados tan pronto como los encuentre en la secuencia. No es necesario que la transmisión finalice antes de que pueda obtener sus resultados.fuente
¿Quizás pueda "usar grep en toda la entrada"? ¿Usando
nc(netcat), o mediantescript, o mediante otras herramientas similares? Especialmente si su archivo de patrones tiene un tamaño manejable (digamos menos de 1000 expresiones regulares).Primer ejemplo : puede hacer
egrepalguna conexión de transmisión: (aquí se muestra un ejemplo connc, pero otros podrían aplicar)(nota: incluso puede:
touch /some/path/results.gzantes de iniciar elnccomando, y tenertail -fen ese archivo (vacío) para no perderse nada. De todos modos, los resultados.gz contendrán todo lo que quería atrapar)segundo ejemplo : incluso podría
egrepen una sesión de shell actualmente en ejecución (y mostrando otra forma de seguir la progresión):egrepes una versión altamente eficiente degrep, en la mayoría de los sistemas (vea algunas informaciones interesantes en: https://swtch.com/~rsc/regexp/regexp1.html )fuente
ses mucho más lento que hacer coincidirsomethingy esto es mucho más lento que hacer coincidirsomething even much longer(esto último permite que la coincidencia de expresión regular salte más grande) porciones de la entrada cuando difieren). En archivos grandes, básicamente "divide" el tiempo para analizarlo por la relación de longitud (es decir, agrupar 1 carácter conocido es casi 40 veces más lento que coincidir con una cadena de 40 caracteres conocidos. t prof it pero es realmente notable.)