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 grep
la 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 XXX
y la cabeza de cada \w+
para ver si es ZZZ
. Si es así entonces es una coincidencia. El -o
cambio a grep
le 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.
- guarde las coincidencias potenciales en una variable lateral, si encuentra ZZZ, imprímalas
- 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 sed
que se eliminen estas líneas, en cuyo caso esta sería una solución alternativa.