AWK do texto com modificação

0

Eu tenho o seguinte arquivo:

hello there. let's try&ACCT=1&bla bla bla&EX=1118&anything ss &SERIAL=1011&DEAL=NO
BLA BLA BLA&TOM=1&ACCT=2&LSLSLSLSL&none=1&EX=1218&lord=1&ok=1&SERIAL=201&flag=non

do qual preciso extrair os valores de campo de ACCT= , EX= e SERIAL= para que a saída se torne:

1,11/18,1011
2,12/18,201

em que EX é sempre um número de 4 dígitos no qual desejo inserir um / como o caractere intermediário.

    
por αԋɱҽԃ αмєяιcαη 08.11.2018 / 14:14

5 respostas

2

Com base em sua entrada de exemplo, que eu coloquei em um arquivo chamado test.in, o seguinte comando awk deve fornecer a saída desejada.

awk -F\& '{for (i=1; i<+NF; i++) {if ($i ~ /^ACCT=/) {acct=$i; sub(/^ACCT=/, "", acct)} if ($i ~ /^EX=/) {ex=$i; sub(/^EX=/, "", ex); sub(/^[0-9][0-9]/, "&/", ex)} if ($i ~ /^SERIAL=/) {serial=$i; sub(/^SERIAL=/, "", serial)}} printf("%s,%s,%s\n", acct, ex, serial)}' test.in

O que isto faz é tratar o & como um separador de campo. Em seguida, ele processa cada campo em uma determinada linha, verificando se esse campo inicia com ACCT =, EX = ou SERIAL =. Se esse campo for encontrado, esse campo será atribuído à variável apropriada. O subcomando é então usado para remover o início dessa variável. Isso apenas fornece o valor associado a essa chave.

Como você precisa de uma barra (/) após os dois primeiros dígitos da chave EX, esse é o outro sub para EX. O "e" comercial (&) é uma referência de retorno que identifica esses dois primeiros dígitos.

Quando todos os campos tiverem sido processados, serão impressos os valores encontrados nessa linha.

Espero que isso ajude.

    
por 08.11.2018 / 17:44
0

Tentei com o método abaixo e funcionou bem como esperado

 k='awk -F "&" '{print NF}' test.txt | sort | uniq| head -1'
for ((h=1;h<=$k;h++)); do awk -v h="$h" -F "&" '$h ~ /ACCT/ || $h ~ /EX/ || $h ~ /SERIAL/{print $h}' test.txt; done

saída

ACCT=1
ACCT=2
EX=1118
SERIAL=1011
EX=1218
SERIAL=201
    
por 08.11.2018 / 17:32
0

Usando sed & cat i atingiu um estágio de solução:)

sed 's/.*ACCT=\([0-9]*\).*//' test > 1
sed 's/.*EX=\([0-9]*\).*//' test > 2
sed 's/.*SERIAL=\([0-9]*\).*//' test > 3

ENTÃO

paste 1 2 3
    
por 08.11.2018 / 20:48
0

Experimente também esta abordagem sed passo-a-passo simples:

sed -r 's/^.*ACCT=//; s/&.*EX=/,/; s/&.*SERIAL=/,/; s/&.*$//; s/,(..)(..),/,\/,/' file
1,11/18,1011
2,12/18,201
    
por 08.11.2018 / 22:14
0

Tentei com os passos abaixo e funcionou bem

 for i in {1..9}; do awk -v i="$i" -F "&" '$i ~ /ACCT/ || $i ~ /SERIAL/{print $i}' p_final.txt; done | awk -F "=" '{print $NF}' >final.txt

for i in {1..9}; do awk -v i="$i" -F "&" '$i ~ /EX/{print $i}' p_final.txt; done| awk -F "=" '{print $NF}'| awk '{print substr($1,1,2)"/"substr($1,3,2)}' >>final.txt


cat final.txt  | sed -n '1~2p' | tr "\n" ","| sed 's/,$//g' | sed  "s/.*/&\n/g"  >output.txt
 cat final.txt  | sed -n '2~2p' | tr "\n" ","| sed 's/,$//g' | sed  "s/.*/&\n/g"  >>output.txt


[root@praveen_linux_example ~]# cat output.txt
1,1011,11/18
2,201,12/18
[root@praveen_l
    
por 09.11.2018 / 10:08