Pregunta usando grep -E con condiciones AND (por ejemplo: (? = / fo) ^ (? = / mo))


Tengo un pequeño problema para averiguar cómo obtener una lista de archivos que tenga:

  1. cadena "/ fo" en ella
  2. Pero no tiene cadena "/ mo"

Estoy intentando descubrir eso en una carpeta con muchos archivos de texto ... Mis intentos fallidos ...

  • grep -lE '(? = / fo) ^ (? = / mo)' *
  • grep -E '(fo) (mo)' *

Estoy atorado aqui... Sugerencias?


2


origen


posible duplicado de grep para "término" y excluir "otro término" - Dennis
Yo diría que no es un duplicado. Esta pregunta se refiere a la ocurrencia en todo el archivo y quiere el nombre del archivo, la otra se trata de hacer coincidir líneas individuales y no necesita el nombre del archivo. Eso hace que esto sea distinto y no trivial. Personalmente, no sabría cómo hacerlo sin decir, por ejemplo, awk. Y, de hecho, las respuestas sobre la otra pregunta no resuelven este problema. - peth
@Dennis: Como respondió user112553, esa no es la misma pregunta que hice ... - confiq
Tu primer párrafo me sonó como si estuvieras buscando / fo en los nombres de los archivos, no en los contenidos de los archivos. - Dennis
Edité la pregunta ... - confiq


Respuestas:


No creo que puedas hacer esto con un pase usando grep.

Una solución grep de dos pasos

Esta solución usa find para pasar archivos en el directorio actual a un while-loop, que a su vez hace el grep'ing deseado:

find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'\0' file; do
  grep -q '/mo' "$file" || grep -l '/fo' "$file" 
done

Una solución awk awk de un paso

parse.awk

BEGINFILE { f1 = f2 = 0 }
$0 ~ pat1 { f1 = 1 }
$0 ~ pat2 { f2 = 1 }
ENDFILE   { if(f1 && !f2) print FILENAME }

Ejecútelo así:

awk -f parse.awk pat1='/fo' pat2='/mo' *

Explicación

GNU awk tiene la BEGINFILE y ENDFILE característica que son bloques ejecutados al principio y al final de un archivo de entrada. Esto nos permite voltear banderas cuando se ven los patrones.

El ejemplo anterior establece los dos indicadores, f1 y f2, basado en si pat1 y pat2 se encuentran en el archivo de entrada actual. Por lo tanto, la ENDFILE block sabe si ambos patrones estaban presentes en el archivo de entrada actual y puede realizar la prueba adecuada.


2