2009-07-01 662 views
40

Estoy tratando de buscar la subcadena "abc" en un archivo específico en Linux/bashUtilizando el signo estrellas en grep

Así que hago:

grep '*abc*' myFile 

no devuelve nada.

Pero si lo hago:

grep 'abc' myFile 

Devuelve partidos correctamente.

Ahora, esto no es un problema para mí. Pero lo que si quiero a grep para una cadena más compleja, por ejemplo

*abc * def * 

¿Cómo podría lograrlo usando grep?

+3

grep sí doesn' t admite comodines en la mayoría de las plataformas. Tienes que usar egrep para usar comodines. Los shells tienen una sintaxis diferente. "*" en el shell es . En egrep, es un operador que dice "0 a muchos de la entidad anterior". En grep, es solo un personaje regular. – PanCrit

+0

@PanCrit: '*' significa lo mismo en grep y egrep: es un * cuantificador * que significa cero o más del átomo precedente. Ese es un concepto completamente diferente al * wildcards * utilizado por el shell. –

Respuesta

63

El asterisco es solo repetition operator, pero necesita decirle lo que repite. /*abc*/ coincide con una cadena que contiene ab y cero o más c (porque el segundo * está en la c; el primero no tiene sentido porque no hay nada para repetir). Si quiere hacer coincidir algo, necesita decir .* - el punto significa cualquier carácter (within certain guidelines). Si solo quiere que coincida con abc, puede decir grep 'abc' myFile. Para su coincidencia más compleja, necesita usar .* - grep 'abc.*def' myFile coincidirá con una cadena que contenga abc seguido de def con algo opcionalmente en medio.

de actualización basado en un comentario:

* en una expresión regular no es exactamente el mismo que * en la consola. En la consola, * es parte de un glob construct, y solo actúa como un comodín (por ejemplo, ls *.log mostrará una lista de todos los archivos que terminan en .log). Sin embargo, en expresiones regulares, * es un modificador, lo que significa que solo se aplica al personaje o grupo que lo precede. Si desea que * en expresiones regulares actúe como un comodín, debe usar .* como se mencionó anteriormente; el punto es un carácter comodín, y la estrella, al modificar el punto, significa encontrar uno o más puntos; es decir. encuentra uno o más de cualquier personaje.

+1

Creo que el cuestionario está confundido acerca de la diferencia entre los comodines de shell y las expresiones regulares. También sospecho que la expresión más complicada sería: grep 'abc. * Def' (al menos un espacio presente, posiblemente dos como escribí). –

+1

En realidad, el cuestionario parece no entender que 'abc' no es lo mismo que '^ abc $' :-D – Massa

+1

Sí, me confundí entre glob y expresiones regulares completas. Uso el * sin un punto para significar que coincida con cualquier cosa en el caparazón. – Saobi

2

Try grep -E para el apoyo de expresión regular extendida

también echar un vistazo a:

The grep man page

8

El "signo del zodiaco" sólo tiene sentido si hay algo en frente de ella. Si no hay una herramienta (grep en este caso) puede tratarlo como un error. Por ejemplo:

'*xyz' is meaningless 
'a*xyz' means zero or more occurrences of 'a' followed by xyz 
+4

El * no tiene sentido; simplemente no tiene su significado habitual (de repetición) sino que significa "Soy una estrella". Coincidiría con una línea que contiene una estrella seguida de x, y y z. –

+1

@Jonathan Depende de la herramienta. –

0

'*' funciona como un modificador para el elemento anterior. Así que 'abc * def' busca 'ab' seguido de 0 o más 'c's seguidas por' def '.

Lo que probablemente quiera es 'abc. * Def' que busque 'abc' seguido de cualquier cantidad de caracteres, seguido de 'def'.

7

El carácter de punto significa que coincide con cualquier carácter, por lo que '. *' Significa cero o más ocurrencias de cualquier carácter. Probablemente quieras usar '. *' En lugar de solo '*'.

Ah, mierda,

1

Uso grep -P - que permite soporte para expresiones regulares Perl estilo.

grep -P "abc.*def" myfile 
4

La expresión se trató, como los que trabajan en la línea de comandos shell en Linux, por ejemplo, que se llama un "glob". Las expresiones Glob no están llenas regular expressions, que es lo que usa grep para especificar las cadenas que se deben buscar. Here es (viejo, pequeño) publicar sobre las diferencias. Las expresiones globales (como en "ls *") son interpretadas por el propio shell.

Es posible traducir de globs a REs, pero normalmente debe hacerlo en su cabeza.

+1

Es solo un pegote si es analizado por el caparazón. Como conserva la cadena de búsqueda dentro de las comillas simples, el intérprete de comandos deja sola la cadena y la pasa intacta en argv a grep. –

4

No está utilizando expresiones regulares, por lo que su variante grep de elección debe ser fgrep, que se comportará como espera.

0

Ésta puede ser la respuesta que está buscando:

grep abc MyFile | grep def 

Lo único es que ... lo hará líneas de salida eran "def" es antes o después de "abc"

Cuestiones relacionadas