¿Cómo hacer que grep solo coincida si toda la línea coincide?


104

Tengo estos:

$ cat a.tmp
ABB.log
ABB.log.122
ABB.log.123

Quería encontrar una coincidencia exacta de ABB.log.

Pero cuando lo hice

$ grep -w ABB.log a.tmp
ABB.log
ABB.log.122
ABB.log.123

los muestra todos.

¿Puedo obtener lo que quería usando grep?

Respuestas:


105

Simplemente especifique los anclajes de expresiones regulares.

grep '^ABB\.log$' a.tmp

2
Se necesitan ambos anclajes (^ y $).
user562374

2
¡Buena esa! ¿Y si estoy usando la expresión regular para la coincidencia de un archivo? "grep -f patrones a.tmp" ??
green69

@ green69 Varios años tarde, pero puede usar sed para agregar los anclajes antes de pasar los patrones a grep:sed -r "s/^(.*)$/^\1$/" patterns.txt | egrep -f - a.tmp
Randoms

155
grep -Fx ABB.log a.tmp

Desde la página de manual de grep:

-F, --fixed-strings
Interpreta PATTERN como una (lista de) cadenas fijas
-x, --line-regexp
Seleccione solo aquellas coincidencias que coincidan exactamente con toda la línea.


2
no pude usar -F desafortunadamente.
Johnyy

@Johnyy -F¿ No ? ¿estás en Solaris? Si el uso de modo/usr/xpg4/bin/grep
Scrutinizer

9
Estoy usando grepdentro de un script bash y esta opción es mejor que usar una expresión regular como se sugiere en la respuesta aceptada. Porque tengo un carácter especial dentro de la variable que estoy buscando (como .) y no tengo que escapar de ellos cuando uso el comando.
Gustavo Straube

1
la mejor respuesta en mi opinión porque permite caracteres especiales sin escapar
Renegado

1
Esto es mejor porque también funciona con variables.
ybenjira

23

Esto es lo que hago, aunque usar anclas es la mejor manera:

grep -w "ABB.log " a.tmp

Como este ... devolverá
Coincidencia de

1
Esto requiere un espacio después ABB.log, que no es el caso general, es decir, fallará la mayor parte del tiempo.
Jahid

3

La mayoría de las sugerencias fallarán si hay un solo espacio inicial o final, lo que importaría si el archivo se está editando a mano. Esto lo haría menos susceptible en ese caso:

grep '^[[:blank:]]*ABB\.log[[:blank:]]*$' a.tmp

Un simple ciclo while-read en shell haría esto implícitamente:

while read file
do 
  case $file in
    (ABB.log) printf "%s\n" "$file"
  esac
done < a.tmp


1

Tengo la intención de agregar una explicación adicional sobre los intentos de OP y otras respuestas también.

También puede usar la solución de John Kugelmans como esta:

grep -x "ABB\.log" a.tmp

citar la cadena y escapar del punto ( .) hace que ya no necesite la -Fbandera.

Debe escapar del .(punto) (porque coincide con cualquier carácter (no solo .) si no se escapa) o usar la -Fbandera con grep. -Fflag lo convierte en una cadena fija (no una expresión regular).

Si no cita la cadena, es posible que necesite una barra invertida doble para escapar del punto ( .):

grep -x ABB\\.log a.tmp


Prueba:

$ echo "ABBElog"|grep -x  ABB.log
ABBElog #matched !!!
$ echo "ABBElog"|grep -x  "ABB\.log"
#returns empty string, no match


Nota:

  1. -x fuerzas para coincidir con toda la línea.
  2. Las respuestas que usan un no escapado .sin -Fbandera son incorrectas.
  3. Puede evitar el -xcambio envolviendo su cadena de patrón con ^y $. En este caso, asegúrese de no usar -F, en su lugar, escape ., porque -Fevitará la interpretación de expresiones regulares de ^y $.


EDITAR: (Añadiendo una explicación adicional con respecto a @hakre):

Si desea hacer coincidir una cadena que comience con -, debe usar --con grep. Lo que sigue --se tomará como entrada (no como opción).

Ejemplo:

echo -f |grep -- "-f"     # where grep "-f" will show error
echo -f |grep -F -- "-f"  # whre grep -F "-f" will show error
grep "pat" -- "-file"     # grep "pat" "-file" won't work. -file is the filename

¿Experimentó realmente que -F faltaba en su caso? Si es así, ¿podría decir qué caso fue?
hakre

@hakre ¿Leíste mi respuesta por completo? Expliqué (bastante claramente) por qué -Fno será necesario si .se escapa correctamente.
Jahid

Por supuesto. Claro, solo pregunto: ¿estaba -Fdisponible cuando escribiste esto? Si no es así, ¿qué sistema estaba usando? No pude encontrar esa información en su respuesta hasta ahora, que incluso ahora es el caso cuando lo releo nuevamente. Realmente seguro, leí tu respuesta por completo al menos dos veces. ;)
hakre

@hakre Por supuesto que -Festaba disponible. (Dije: "o usar la -Fbandera con grep")
Jahid

Gracias por la información. Solo queda una pequeña pregunta: si -Fes la respuesta, ¿por qué preocuparse por escapar? ¿Cuál es tu opinión sobre eso?
hakre


-1
    $ cat venky
    ABB.log
    ABB.log.122
    ABB.log.123

    $ cat venky | grep "ABB.log" | grep -v "ABB.log\."
    ABB.log
    $

    $ cat venky | grep "ABB.log.122" | grep -v "ABB.log.122\."
    ABB.log.122
    $

1
Esto también hará coincidir los archivos que terminan con ABB.log y los puntos deben escaparse.
Escrutador

-1

Funciona para mi :

grep "\bsearch_word\b" text_file > output.txt  

\b indica / establece límites.

Parece funcionar bastante rápido


Esto también coincide con cualquier línea que contenga search_wordlímites de palabras separados. Por ejemplo, coincidiría con la línea "foo barra de palabras de búsqueda".
Rohan Singh

-2

Esto es con HPUX, si el contenido de los archivos tiene espacio entre palabras, use esto:

egrep "[[:space:]]ABC\.log[[:space:]]" a.tmp


El OP quería hacer coincidir toda la línea, no una palabra delimitada por espacios dentro de la línea.
Keith Thompson


-3

Necesitaba esta función, pero también quería asegurarme de no devolver líneas con un prefijo antes de ABB.log:

  • ABB.log
  • ABB.log.122
  • ABB.log.123
  • 123ABB.log

grep "\WABB.log$" -w a.tmp

Esto solo coincidirá si \Wse satisface el liderazgo , que es cualquier carácter que no sea un espacio en blanco, entonces xABBxlog.
bschlueter
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.