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
-M
opción que es únicapcregrep
y se usa para unir varias líneas (pcregrep
extrae 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(?!...)
coincideFoo
siempre...
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
pcregrep
como lo sugiere @StephaneChazelas.Esto debería funcionar:
La idea es utilizar el
-A
interruptor de grep para generar las líneas coincidentes y las N líneas siguientes. Luego pasa el resultado a través de aygrep Bar
si 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.cpp
se devuelve a pesar de contenerBar
porque la línea conBar
es 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
Foo
nada. Este evita que:fuente
Foo
. Te faltan citas.Foo
y 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