Como gerar apenas uma coluna que possui vizinhos constantes?

Como gerar apenas uma coluna que possui vizinhos constantes?

ENTRADA

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

SAÍDA

Y1Y
Y2Y

As linhas de entrada podem variar.. apenas o XXX antes de Y1Y e o ZZZ depois de Y1Y são constantes (são vizinhos de XXX e ZZZ assim). Y1Y pode ser qualquer coisa, ex.: Y1Y, Y2Y, Y1T, etc.

P:como posso obter a SAÍDA com awk ou sed ou grep? (ou existe alguma ferramenta melhor para isso?)

ATUALIZAR(problema): por que não funciona quando se tem "." no 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 ~] 

Responder1

Você pode usar grepo recurso PCRE fornecido para fazer isso:

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

Detalhes

Esta solução faz uso do recurso lookbehind e lookahead do PCRE, que pode corresponder a strings de comprimento fixo.

O texto acima olha atrás de cada um \w+para ver se é XXXe na cabeça de cada um \w+para ver se é ZZZ. Se for, então é uma correspondência. A -oopção grepdiz para imprimir apenas as correspondências, ou seja \w+, .

Acompanhamento, você pode fazer isso com sed?

Não creio que esse problema possa ser resolvido usando sed. Existem 2 abordagens, a meu ver.

  1. salve possíveis correspondências em uma variável secundária, se você encontrar ZZZ, imprima-as
  2. s/XXX ..nossa string.. ZZZ/ ..nossa string../

O número 1 parece bastante trabalhoso, então nem vou tentar. Aqui está o que acontece com a abordagem nº 2.

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

Portanto, ele pode encontrar as correspondências perfeitamente, mas não faz nada pelas linhas que não correspondem. Pode haver uma maneira de instruir seda exclusão dessas linhas; nesse caso, essa seria uma solução alternativa.

informação relacionada