Cómo encontrar líneas que comienzan con **

8

Necesito encontrar si alguna línea en un archivo comienza **.

No puedo entender cómo hacerlo porque *el shell lo interpreta como un comodín.

grep -i "^2" test.out

funciona si la línea comienza con un 2 pero

grep -i "^**" test.out 

Obviamente no funciona.

(También necesito saber si esta línea termina con un )pero aún no lo he intentado).

Shar Hunter
fuente

Respuestas:

18

Usa el \personaje para escapar del * y convertirlo en un personaje normal.

grep '^\*\*' test.out

También tenga en cuenta la comilla simple 'y no la comilla doble "para evitar que el shell expanda cosas

Stephen Harris
fuente
3
El primero *no necesita escapar en este caso particular, fwiw.
don_crissti
55
Aunque no tiene que escaparse, no escapar del primer asterisco será más confuso para un observador casual, como si estuviera haciendo coincidir "cualquier número de comienzos de líneas seguidos de un asterisco". Cualquier cosa que haga que una expresión regular sea más intuitiva para un mantenedor es una buena idea. =)
Compilador conspicuo
1
El uso de comillas dobles también evitaría la expansión, no solo comillas simples. Consejos equivocados aquí.
rems4e
@ rems4e usando comillas dobles evitaría que el shell expanda los asteriscos, pero no interprete las barras diagonales inversas. Con comillas dobles, tendría que usar grep "^\\*\\*"para que grep reciba la ^\*\*cadena que necesita para evitar interpretar los asteriscos como cuantificadores de expresiones regulares.
Aaron
7

Como quería comprobar la línea que comienza **y termina con ), puede combinar dos grepoperaciones como esta,

grep '^*\*' test.out | grep ')$'

O con un solo grepcomando como este,

grep -E '^\*\*.*\)$' test.out

Explicación

  • ^\*\* : línea de partido que comienza con **
  • .* : coincide con todo después **
  • \)$: línea de coincidencia que también tiene )al final de la línea.
Rahul
fuente
3

No es la cáscara

Ninguna de las respuestas hasta ahora ha tocado el problema real. Sería útil explicar por qué no funciona como espera.

grep -i "^**" test.out

Debido a que usted ha citado el patrón de grep , *está no expandido en la cáscara. Se pasa a grep como está. Esto se explica en la página del manual [1] para bash [2] :

El encerrar caracteres entre comillas dobles conserva el valor literal de todos los caracteres dentro de las comillas, con la excepción de $, `, \ y, cuando la expansión del historial está habilitada,!.

Es regular expresiones regulares ordinarias

Una expresión regular es un patrón que describe un conjunto de cadenas.

*Es uno de los patrones clave en las expresiones regulares. Por defecto, grep lo interpreta de la siguiente manera:

* The preceding item will be matched zero or more times.

Esto significa que su patrón tal como está, ^**no tiene mucho sentido. Posiblemente trata de hacer coincidir el comienzo de la línea cero o más veces , dos veces. Lo que sea que eso signifique.

La solución es citarlo :

Cualquier meta-carácter con significado especial puede ser citado precediéndolo con una barra invertida.

grep -i "^\*\*" test.out


[1] No recomiendo leerlo. Por favor, use man dasho similar en su lugar.

[2] No se dio ningún shell, así que supongo que bash .

tubo
fuente
2

Otras opciones.

Puedes usar sedo awktambién

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Para conocer líneas que terminan con el )uso también grepo sedoawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out
tachomi
fuente
Gracias a todos ! Realmente aprecio la ayuda en este!
Shar Hunter el
1
Y la línea awk combinada: '/^*\*/&&/)$/'...
jasonwryan
0

Esta es la versión completamente sin comillas: grep ^\\*\\* test.out. Para pasar una barra invertida literal del shell a grep, se debe escapar.

Esto funciona siempre que no tenga archivos en el directorio que comiencen ^\y contengan otra barra invertida.

Vencer a Bolli
fuente