¿Cómo generar solo una columna que tenga vecinos constantes?

¿Cómo generar solo una columna que tenga vecinos constantes?

APORTE

AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU

PRODUCCIÓN

Y1Y
Y2Y

Las líneas de entrada pueden variar... solo el XXX antes de Y1Y y el ZZZ después de Y1Y son constantes (son vecinos de XXX y ZZZ así). Y1Y podría ser cualquier cosa, por ejemplo: Y1Y, Y2Y, Y1T, etc.

P:¿Cómo puedo obtener la SALIDA con awk o sed o grep? (¿O hay alguna herramienta mejor para esto?)

ACTUALIZAR(problema): ¿por qué no funciona cuando se tiene "." en el Y1Y?

[user@notebook ~] echo 'XXX Y1Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
Y1Y
[user@notebook ~] echo 'XXX Y1.Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
[user@notebook ~] 

Respuesta1

Puede utilizar grepla función PCRE que proporciona para hacer esto:

$ grep -Po "(?<=XXX )\S+(?= ZZZ)" data.txt 
Y1Y
Y2Y

Detalles

Esta solución utiliza la función de búsqueda hacia atrás y hacia adelante de PCRE, que puede hacer coincidir cadenas de longitud fija.

Lo anterior mira detrás de cada \w+para ver si es XXXy la cabeza de cada \w+para ver si es ZZZ. Si es así entonces es una coincidencia. El -ocambio a greple indica que imprima solo las coincidencias, es decir \w+.

Seguimiento, ¿puedes hacerlo con sed?

No creo que este problema se pueda resolver usando sed. Hay 2 enfoques como yo lo veo.

  1. guarde las coincidencias potenciales en una variable lateral, si encuentra ZZZ, imprímalas
  2. s/XXX ..nuestra cadena.. ZZZ/ ..nuestra cadena../

El número 1 parece una buena cantidad de trabajo, así que ni siquiera voy a intentarlo. Esto es lo que sucede con el enfoque número 2.

$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt 
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU

Por lo tanto, puede encontrar coincidencias sin problemas, pero no hace nada con las líneas que no coinciden. Podría haber una manera de indicar sedque se eliminen estas líneas, en cuyo caso esta sería una solución alternativa.

información relacionada