verdadero varios varias utilizar usos usar texto sólo start sobre siguientes regulares que puede patrones para palabras palabra mostrará líneas los las falso expresiones exacta ejemplos egrep cuál con comprimidos comienzan comandos comando caracteres cadenas buscar archivos archivo anidado unix grep tail

unix - varios - usar grep para buscar archivos



Grep un archivo de registro para la última aparición de una cadena entre dos cadenas (5)

Otra solución que grep sería sed:

tac file | sed -n ''0,/<tag>/(.*/)<//tag>/s///1/p''

tac file imprime el archivo en el orden inverso ( cat hacia atrás), luego sed procede desde la línea de entrada 0 hasta la primera aparición de <tag>.*</tag> , y sustituye <tag>.*</tag> con solo el parte que estaba dentro de <tag> . El indicador p imprime la salida, que fue suprimida por -n .

Editar: Esto no funciona si <tag> y </tag> están en líneas diferentes. Todavía podemos usar sed para eso:

tac file | sed -n ''/<//tag>/,$p; /<tag>/q'' | sed ''s/.*<tag>//; s/<//tag>.*//'' | tac

De nuevo usamos tac para leer el archivo hacia atrás, luego el primer comando sed lee desde la primera aparición y se cierra cuando lo encuentra. Solo se imprimen las líneas intermedias. Luego lo pasamos a otro proceso sed para despojarlo y finalmente revertir las líneas nuevamente con tac .

Tengo un archivo de registro trace.log . En él, necesito grep para el contenido incluido dentro de las cadenas <tag> y </tag> . Hay varios conjuntos de este par de cadenas, y solo necesito devolver el contenido entre el último conjunto (en otras palabras, desde la tail del archivo de registro).

Crédito adicional: ¿De alguna manera puedo devolver el contenido contenido en las dos cadenas solo si el contenido contiene "testString"?

Gracias por mirar.

EDITAR: Los parámetros de búsqueda y están contenidos en diferentes líneas con alrededor de 100 líneas de contenido que los separan. El contenido es lo que busco ...


Un poco de awk no probado que maneja múltiples líneas:

awk '' BEGIN {retain="false"} /</tag>/ {retain = retain + $0; keep="false"; next} /<tag>/ {keep = "true"; retain = $0; next} keep == "true" {retain = retain + $0} END {print retain} '' filename

Comenzamos simplemente leyendo el archivo; cuando golpeamos el, comenzamos a mantener las líneas. Cuando golpeamos el, nos detenemos. Si golpeamos a otro, borramos la cadena retenida y comenzamos nuevamente. Si quieres todas las cadenas, imprime en cada


Use tac para imprimir el archivo al revés y luego grep -m1 para simplemente imprimir un resultado. La mirada hacia atrás y hacia adelante verifica el texto entre <tag> y </tag> .

tac a | grep -m1 -oP ''(?<=tag>).*(?=</tag>)''

Prueba

Dado este archivo

$ cat a <tag> and </tag> aaa <tag> and <b> other things </tag> adsaad <tag>and last one</tag> $ tac a | grep -m1 -oP ''(?<=tag>).*(?=</tag>)'' and last one

Actualizar

EDITAR: Los parámetros de búsqueda y están contenidos en diferentes líneas con alrededor de 100 líneas de contenido que los separan. El contenido es lo que busco ...

Entonces es un poco más complicado:

tac file | awk ''/<//tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p'' | tac

La idea es invertir el archivo y usar una bandera p para verificar si la <tag> ya apareció o no. Comenzará a imprimirse cuando </tag> aparezca y termine cuando <tag> venga (porque estamos leyendo al revés).

  • split($0, a, "</tag>"); $0=a[1]; obtiene los datos antes de </tag>
  • split($0, a, "<tag>" ); $0=a[2]; obtiene los datos después de <tag>

Prueba

Dado un archivo como este:

<tag> and </tag> aaa <tag> and <b> other thing come here and here </tag> some text<tag>tag is starting here blabla and ends here</tag>

El resultado será:

$ tac a | awk ''/<//tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p'' | tac tag is starting here blabla and ends here


Si, como yo, no tienes acceso a tac porque tu administrador de sistema no jugará bola, puedes probar:

grep pattern file | tail -1


perl -e ''$/=undef; $f=<>; push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1]'' ex.txt

Crédito adicional: ¿De alguna manera puedo devolver el contenido contenido en las dos cadenas solo si el contenido contiene "testString"?

perl -e ''$/=undef; $f=<>; push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1] if ($a[-1]~=/teststring/);'' ex.txt