bash - varias - grep varios patrones
¿Cómo grep, excluyendo algunos patrones? (8)
Me gustaría encontrar líneas en los archivos con la aparición de algún patrón y la ausencia de algún otro patrón. Por ejemplo, necesito encontrar todos los archivos / líneas, incluido el loom
excepto los que tienen gloom
. Entonces, puedo encontrar el loom
con el comando:
grep -n ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
Ahora, quiero buscar loom
excluyendo gloom
. Sin embargo, los dos siguientes comandos fallaron:
grep -v ''gloom'' -n ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n ''loom'' -v ''gloom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
¿Qué debo hacer para lograr mi objetivo?
EDITOR 1: Quiero decir que el loom
y la gloom
son las secuencias de caracteres (no necesariamente las palabras). Entonces, necesito, por ejemplo, bloomberg
en el resultado del comando y no necesito ungloomy
.
EDICION 2: hay una muestra de mis expectativas. Ambas líneas siguientes están en salida de comando:
Me enfrenté a los iconos que se alzaban a través del velo del incienso.
Arty está descendiendo en un día sombrío .
Ambas líneas siguientes no están en salida de comando:
Es sombrío, terrible, gran muck doolders o cloods.
En la ronda sudoeste de la sala heigh pyntit
¿Qué tal solo encadenar a los greps?
grep -n ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v ''gloom''
Otra solución sin encadenar grep
:
egrep ''(^|[^g])loom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
Entre paréntesis, excluyes el carácter g
antes de que ocurra el loom
, a menos que loom
sea el primer carácter de la línea.
Puede usar grep -P
(perl regex) compatible negative lookbehind
:
grep -P ''(?<!g)loom/b'' ~/projects/**/trunk/src/**/*.@(h|cpp)
Agregué /b
para los límites de palabras.
grep -n ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v ''gloom''
Solo use awk, es mucho más simple que grep para que pueda expresar claramente las condiciones compuestas.
Si desea saltear líneas que contienen tanto loom
como gloom
:
awk ''/loom/ && !/gloom/{ print FILENAME, FNR, $0 }'' ~/projects/**/trunk/src/**/*.@(h|cpp)
o si quieres imprimirlos:
awk ''/(^|[^g])loom/{ print FILENAME, FNR, $0 }'' ~/projects/**/trunk/src/**/*.@(h|cpp)
y si la realidad es que solo quieres líneas donde el loom
aparece como una palabra en sí misma:
awk ''//<loom/>/{ print FILENAME, FNR, $0 }'' ~/projects/**/trunk/src/**/*.@(h|cpp)
/ * ¿Puedes estar buscando algo como esto?
grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`
Los BACKQUOTES se utilizan como corchetes para comandos, por lo que en este caso con -l
habilitado, el código en BACKQUOTES le devolverá los nombres de los archivos, luego con -vn para hacer lo que desee: tener nombres de archivos, números de lienzo y también las líneas reales .
ACTUALIZACIÓN O con xargs
grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"
Espero que ayude.*/
Por favor ignora lo que escribí arriba, es basura.
grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom"
#this part gets the filenames with "loom"
#this part gets the lines with "loom"
#this part gets the linenumber,
#filename and actual line
Pregunta: busque ''telar'' excluyendo ''oscuridad''.
Responder:
grep -w ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
Un poco viejo, pero bueno ...
La solución más votada de @houbysoft no funcionará, ya que excluirá cualquier línea con "pesimismo", incluso si tiene "telar". De acuerdo con las expectativas de OP, necesitamos incluir líneas con "telar", incluso si también tienen "pesimismo" en ellas. Esta línea debe estar en la salida "Arty está descendiendo en un día sombrío", pero esto será excluido por un grep encadenado como
grep -n ''loom'' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v ''gloom''
En cambio, el ejemplo egrep regex de Bentoy13 funciona mejor
egrep ''(^|[^g])loom'' ~/projects/**/trunk/src/**/*.@(h|cpp)
ya que incluirá cualquier línea con "telar" en ella, independientemente de si tiene o no "oscuridad". Por otro lado, si solo tiene tristeza, no lo incluirá, que es precisamente el comportamiento que desea OP.