Supongamos que quiero buscar en un árbol completo todos los archivos CPP donde aparece "Foo". Yo podría hacer:
find . -name "*.cpp" | xargs grep "Foo"
Ahora suponga que quiero enumerar solo aquellas instancias en las que alguna otra cadena, digamos "Bar", no aparece dentro de las 3 líneas del resultado anterior.
Entonces dados dos archivos:
a.cpp
1 Foo
2 qwerty
3 qwerty
b.cpp
1 Foo
2 Bar
3 qwerty
Me gustaría construir una búsqueda simple donde se encuentre "Foo" de a.cpp, pero "Foo" de b.cpp no.
¿Hay alguna manera de lograr esto de una manera bastante simple?

Respuestas:
Con
pcregrep:La clave está en la
-Mopción que es únicapcregrepy se usa para unir varias líneas (pcregrepextrae más datos del archivo de entrada según sea necesario cuando se camina, el RE lo exige).(?!...)es el operador RE de anticipación negativa perl / PCRE.Foo(?!...)coincideFoosiempre...que no coincida con lo que sigue....siendo(?:.*\n){0,2}.*Bar(.que no coincida con un carácter de nueva línea), que es de 0 a 2 líneas seguidas por una línea que contieneBar.fuente
pcregrep? Nunca he oído hablar de eso antes.(?!...)negativo de anticipaciónperl.No importa, solo utilícelo
pcregrepcomo lo sugiere @StephaneChazelas.Esto debería funcionar:
La idea es utilizar el
-Ainterruptor de grep para generar las líneas coincidentes y las N líneas siguientes. Luego pasa el resultado a través de aygrep Barsi eso no coincide (salir> 0), entonces repite el nombre del archivo.Si sabe que tiene nombres de archivo sanos (sin espacios, líneas nuevas u otros caracteres extraños), puede simplificarlo para:
Por ejemplo:
Tenga en cuenta que
c.cppse devuelve a pesar de contenerBarporque la línea conBares más de 3 líneas despuésFoo. Puede controlar el número de líneas que desea buscar cambiando el valor pasado a-A:Aquí hay uno más corto (suponiendo que lo use
bash):IMPORTANTE
Como Stephane Chazelas señaló en los comentarios, las soluciones anteriores también imprimirán archivos que no contienen
Foonada. Este evita que:fuente
Foo. Te faltan citas.Fooy lo arreglé, pero no entiendo tu punto sobre múltiples instancias deFoo. Debe tratar con ellos correctamente.No probado, estoy en mi teléfono:
algo como eso.
fuente