Como posso extrair uma string específica de um arquivo?

0

Estou tendo dificuldades em analisar meus dados. No arquivo mostrado abaixo, quero pegar os caracteres depois de BIG**20021208*00001** . Eu tentei sed '/BIG.20021208.00001\**/!d;s///;s/\*.*//' mas não funciona. Eu acho que o problema tem a ver com o separador de linha ( ).

BIG*20021208*00001**A1001… 
TO*7284*0001…BIG*20021208*00001**A999… 
NN*ST*XYZ Test Corporation*9*122334455… 
NU*987 ELS.… 
N4**NY*98765… 
ITD*01*3*2**30**45*****60… 
N3*123 Highway Street… 
N4**12345… 
ITD*001*3*2**30**30*****60… 
BIG*20021208*00001**8263-83313… 
ITD*001*3*2**30**30*****60… 
BIG*20021208*00001**8263-83313… 

Minha saída esperada é:

A1001
8263-83313
8263-83313
    
por user74775 08.07.2014 / 02:12

2 respostas

3

Existem várias maneiras de fazer isso. Por exemplo:

  • grep

    grep -oP 'BIG\*20021208\*00001\**\K[A-Z0-9-]+' file
    

    Explicação

    O -o faz o grep imprimir apenas a parte correspondente de uma linha e o -P ativa Expressão regular compatível com Perl Sintaxe (PCRE). O \K nos PCREs faz com que o que foi correspondido até aquele ponto seja descartado (e, portanto, não seja impresso, por causa de -o ). [A-Z0-9-] é uma classe de caracteres que corresponde a qualquer letra maiúscula de A a Z, qualquer número ou - e que pode ser repetido uma ou mais vezes ( + ).

    Se as strings de destino também puderem conter letras minúsculas, basta executar grep com o sinal -i ou alterar a classe de caracteres para [a-zA-Z0-9-] .

    --- ou ---

    grep -oP 'BIG\*20021208\*00001\**\K.+(?=…)' file
    

    Explicação

    Isso é exatamente como acima, mas aqui há uma antecipação positiva ( (?=…) ), o que significa que .+ corresponderá apenas se preceder a .

  • sed

    sed -rn 's/…//g;s/.*BIG\*20021208\*00001\**//p;' file
    

    Explicação

    O s/from/to/ é o operador de substituição do sed. Ele substitui from por to . O primeiro substitui por nada, ele os exclui (o g garante que isso seja feito para todas as correspondências na linha). O segundo exclui tudo, desde o início da linha ( .* ) até BIG*20021208*00001 ( * tem um significado especial em expressões regulares, portanto, precisa ser escapado com \* ) e, em seguida, 0 ou mais asteriscos (% código%). Combinados, eles excluem tudo, exceto o que você deseja.

    O \** suprime a impressão de qualquer saída. O -n no final do segundo operador de substituição faz com que o sed imprima todas as mentiras em que a substituição foi bem-sucedida.

  • awk

    awk -F'[*…]' '/BIG\*20021208\*00001\**/{print $(NF-1)}' file
    

    Explicação

    O separador de campos de entrada do p set do awk para -F ou * . Isso significa que o penúltimo campo será o que você deseja. O comando acima imprime em linhas que correspondem a .

  • Perl

    perl -lne '/BIG\*20021208\*00001\**(.*)…/ && print "$1"' file
    

    Explicação

    O BIG*20021208*00001* faz o perl ler sua linha de entrada por linha e aplicar o script dado por -n a ele. O -e adiciona um caractere de nova linha a cada chamada -l . O comando acima tentará corresponder à cadeia de interesse (veja a explicação do exemplo sed acima) e imprimi-lo se for bem-sucedido.

    Você também pode usar a mesma abordagem do exemplo do awk:

    perl -F'[*…]' -lane '/BIG\*20021208\*00001\**/ && print "$F[$#F]"' file
    
por 08.07.2014 / 02:34
2

Usando awk :

awk -F\* '/^BIG/ {gsub(/…/,""); print $NF}' file
A1001
8263-83313
8263-83313
    
por 09.07.2014 / 03:30