2010-08-06 11 views
9

Básicamente estoy grepping con una expresión regular en. En el resultado, me gustaría ver solo las cadenas que coinciden con mi registro exp.En grep en Ubuntu, ¿cómo puedo mostrar solo la cadena que coincide con la expresión regular?

En un grupo de archivos XML (en su mayoría son archivos de una sola línea con grandes cantidades de datos en una línea), me gustaría obtener todas las palabras que comienzan con MAIL_.

Además, me gustaría que el comando grep en el intérprete de comandos muestre solo las palabras que coinciden y no toda la línea (que es el archivo completo en este caso).

¿Cómo puedo hacer esto?

He tratado

grep -Gril MAIL_* . 
grep -Grio MAIL_* . 
grep -Gro MAIL_* . 

Respuesta

13

En primer lugar, con GNU grep que se instala con Ubuntu, -G indicador (use regexp básico) es el valor predeterminado, por lo que puede omitirlo, pero, lo que es mejor, utilizar expresiones regulares extendida con -E.

-r marca significa búsqueda recursiva dentro de los archivos de un directorio, esto es lo que necesita.

Y, tiene razón para usar -o para imprimir la parte correspondiente de una línea. Además, para omitir los nombres de los archivos necesitarás un indicador -h.

El único error que ha cometido es la expresión regular. Te perdiste la especificación del carácter antes de *. Su comando debería tener este aspecto:

grep -Ehro 'MAIL_[^[:space:]]*' . 

Ejemplo de salida (no recursiva):

$ echo "Some garbage MAIL_OPTION comes MAIL_VALUE here" | grep -Eho 'MAIL_[^[:space:]]*' 
MAIL_OPTION 
MAIL_VALUE 
+0

genial ... funciona, pero una pregunta rápida ¿cómo hago si sé que las cosas MAIL_ * están presentes como type = "MAIL_ *" o> MAIL _ * AMM

+0

No lo entiendo ¿Podrías reformular tu pregunta? ¿Quieres ver los personajes que rodean tu material de MAIL_XXX? ¿Desea ver "y <> en la salida del comando grep? – thor

+0

si su MAIL_ * solo puede contener caracteres alfabéticos (a-z), entonces puede cambiar la expresión regular a 'MAIL _ [[: alfa:]] *' – thor

2
grep -o or --only-matching 

salidas sólo el texto coincidente en lugar de líneas completas, pero el problema podría ser su expresión regular que no es restrictiva o lo suficientemente codiciosos y en realidad coincide con el archivo completo.

+0

ahora el tipo de palabras que quiero están presentes como esta en el archivo type = "MAIL_ABC_CDE" type = "MAIL_XXX_AAA_AAA" etc puede haber cualquier número de _ ¿Cuál debería ser el registro que debería usar? alguna idea sobre eso? – AMM

5

Pruebe el siguiente comando

grep -Eo 'MAIL_[[:alnum:]_]*' 
0

Desde su comentario a la respuesta de Thor le parece también quieren para distinguir si el texto MAIL_.* es un nodo de texto o un atributo, no solo para aislarlo cada vez que aparece en el documento XML. Grep no puede analizar XML, you need a proper XML parser for that.

Un analizador xml de línea de comandos es xmlstarlet. Está empaquetado en Ubuntu.

Su uso en este ejemplo ejemplo de archivo de archivo:

$ cat test.xml 
<some_root> 
    <test a="MAIL_as_attribute">will be printed if you want matching attributes</test> 
    <bar>MAIL_as_text will be printed if you want matching text nodes</bar> 
    <MAIL_will_not_be_printed>abc</MAIL_will_not_be_printed> 
</some_root> 

para la selección de los nodos de texto que puede utilizar:

$ xmlstarlet sel -t -m '//*' -v 'text()' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*' 
MAIL_as_text 

y para seleccionar atributos:

$ xmlstarlet sel -t -m '//*[@*]' -v '@*' -n test.xml | grep -Eo 'MAIL_[^[:space:]]*' 
MAIL_as_attribute 

una breve explicación:

  • //* es una expresión XPath que selecciona todos los elementos en el documento y text() salida el valor de sus nodos de texto los niños, por lo tanto, todo excepto los nodos de texto se filtra a cabo
  • //*[@*] es una expresión XPath que selecciona todos los atributos en el documento y entonces @* da salida a su valor
Cuestiones relacionadas