Como exportar apenas uma coluna que tenha vizinhos constantes?

2

ENTRADA

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

OUTPUT

Y1Y
Y2Y

As linhas de entrada podem variar .. apenas o XXX antes do Y1Y e o ZZZ após o Y1Y é constante (eles são os vizinhos de XXX e ZZZ assim). YYY poderia ser qualquer coisa, ex .: Y1Y, Y2Y, Y1T, etc.

P: como posso obter o OUTPUT com awk ou sed ou grep? (ou existe alguma ferramenta melhor para isso?)

UPDATE (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 ~] 
    
por gasko peter 03.10.2013 / 15:24

1 resposta

1

Você pode usar o grep e o recurso PCRE que ele fornece para fazer isso:

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

Detalhes

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

O texto acima analisa cada \w+ para ver se é XXX e a cabeça de cada \w+ , se é ZZZ . Se for, então é um jogo. A alteração de -o para grep diz para imprimir apenas as correspondências, ou seja, \w+ .

Acompanhamento, você pode fazer isso com sed?

Eu não acho que esse problema possa ser resolvido usando sed . Existem duas abordagens que eu vejo.

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

Não. Parece ser uma quantidade razoável de trabalho, então não vou nem tentar. Veja o que acontece com a abordagem nº 2.

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

Por isso, pode encontrar as correspondências muito bem, mas não faz nada para linhas que não correspondem. Pode haver uma maneira de instruir sed para excluir essas linhas e, nesse caso, essa seria uma solução alternativa.

    
por 03.10.2013 / 15:43

Tags