awk + como capturar endereço de e-mail entre caracteres

3

Eu tenho uma longa lista de e-mails entre os caracteres < e > :

smeimebv2t <jdyefc@nsuwtcvc>; jdedyvt <ejd2ydt2@dv2dg2vgv>; didi2jd2m     <i2dmi32@hd2vdg >; 3idm23i2m <2udhu2@cdrrc>
.
.
.

Como posso usar um forro awk ou perl para capturar somente os endereços de e-mail entre o < > ?

exemplo:

more results.out

jdyefc@nsuwtcvc
ejd2ydt2@dv2dg2vgv
i2dmi32@hd2vdg
2udhu2@cdrrc
    
por yael 24.03.2017 / 13:44

4 respostas

9

A maneira mais simples de pensar é usar o GNU grep :

$ grep -Po '<\K[^>]+(?=>)' file 
jdyefc@nsuwtcvc
ejd2ydt2@dv2dg2vgv
i2dmi32@hd2vdg 
2udhu2@cdrrc

O -o significa "apenas imprimir região correspondente da linha" e o -P ativa expressões regulares compatíveis com Perl. Isso nos permite usar \K , o que significa "não considerar nada comparado a este ponto como parte da correspondência" e positivo lookaheads . Assim, a regex corresponderá a < e, em seguida, a qualquer trecho de caracteres não > seguidos por > .

Observe que isso também corresponderá a <foo> , que não é um e-mail. Para restringir apenas para e-mails (strings com @ ), você pode usar:

grep -Po '<\K[^>]+@[^>]+(?=>)' file 
    
por 24.03.2017 / 13:55
4
perl -lne 'print for /<\K[^>]+/g'
    
por 24.03.2017 / 13:55
4

Usando o gawk:

awk -v RS="[<>]" '/@/' 
    
por 24.03.2017 / 15:24
1

Outra variante:

perl -lne 'print $1 while /<(.*?)>/g'

A captura de parênteses para $1 , .*? torna a correspondência não-gulosa, ou seja, pára assim que possível.

com awk :

awk -F'<' '{ for(i = 2 ; i <= NF ; i++) { sub(/>.*/, "", $i); print $i; } } ' 

Divida a linha em < , ignore a primeira parte, imprima outras depois de remover qualquer coisa que comece com > . Isso imprimirá o resto da linha se não houver > após < .

    
por 24.03.2017 / 15:18