Estoy tratando de construir una búsqueda grep que busque un término pero excluya líneas que tienen un segundo término. Quería usar varias -e "pattern"
opciones, pero eso no funcionó.
Aquí hay un ejemplo de un comando que probé y el mensaje de error que generó.
grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory
Me parece que se -v
aplica a todos los términos / patrones de búsqueda. A medida que esto se ejecuta pero luego no se incluye search term
en los resultados.
grep -i -E "search term" -ve "exclude term"
Respuestas:
Para y expresiones con grep necesitas dos invocaciones:
Si los términos que está buscando no son expresiones regulares, utilice la coincidencia de cadena fija (
-F
), que es más rápida:fuente
A menos que invoquemos grep dos veces, solo se me ocurre una forma de lograrlo. Involucra expresiones regulares compatibles con Perl (PCRE) y algunas afirmaciones de observación bastante extravagantes .
Para buscar foo excluyendo coincidencias que contengan barra , puede usar:
Así es como funciona:
(?!bar)
coincide con cualquier cosa que no se barra sin consumir caracteres de la cadena. Luego.
consume un solo personaje.^((?!bar).)*
repite lo anterior desde el inicio de la cadena (^
) hasta el final ($
). Fallará sibar
se encuentra en un punto dado, ya(?!bar)
que no coincidirá.(?=^((?!bar).)*$)
se asegura de que la cadena coincida con el patrón anterior, sin consumir caracteres de la cadena.foo
busca a foo como de costumbre.¿Encontré este truco en la expresión regular para que coincida con la cadena que no contiene una palabra? . En la respuesta de Bart Kiers , puede encontrar una explicación mucho más detallada de cómo funciona la perspectiva negativa.
fuente
Si desea hacer esto de una sola vez, puede usar awk en lugar de grep.
Formato:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
Ejemplos:
echo "hello there" | awk '/hello/ && !/there/'
No devuelve nada
echo "hello thre" | awk '/hello/ && !/there/'
Devoluciones: hola thre
echo "hllo there" | awk '/hello/ && !/there/'
No devuelve nada
Para múltiples patrones, puede usar paréntesis para agruparlos.
Ejemplos:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
Devoluciones: hola thre
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
Devoluciones: hola tres
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
No devuelve nada
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
No devuelve nada
fuente
ls --color=always | awk '/hello/ && !/goodbye/'
grep -R
en varios archivos de código usando la línea de comandos de Ubuntu.De mis experimentos no parece que haya mucha diferencia si canaliza sus términos de exclusión a través de
grep
osed
. Sed tiene algunas otras características útiles de reemplazo de texto que a menudo uso para filtrar mejor la salida de archivos de registro. Así que voy a usar sed ya que combino bastantes filtros en sed.fuente
grep -F
lugar degrep -E
y no lo use-i
si no lo necesita.sed
;)