Problema do AWK usando scripts unix

0

Eu tenho este arquivo

AK3*BPS*2
AK4*8*0510*1
AK3*RMT*12
AK4*1*0128*7*CR

e eu quero essa saída

BPS 2  1
RMT 12 7 CR

Estou usando este comando

awk -F* '$1=="AK3" { print $2, $3 } "\c" ($1=="AK4" { print $4, $5 }' $FileHome/badfile_$session_num.txt >>  $FileHome/input_output_record.txt

mas estou recebendo esse resultado

BPS 2
1
RMT 12
7 CR

Qualquer sugestão será apreciada

    
por Antonio Pizarro 14.12.2017 / 15:55

5 respostas

0

Você parece querer:

  1. Os dois últimos campos de cada linha AK3 , seguidos por
  2. Campos quatro e cinco da linha AK4 (o campo cinco pode estar faltando).
$ awk -F '*' '/^AK3/ { printf("%s\t%s", $2, $3) } /^AK4/ { printf("\t%s\t%s\n", $4, $5) }' data.in
BPS     2       1
RMT     12      7       CR
    
por 14.12.2017 / 16:13
0

Outra maneira é controlar diretamente o separador de registros de saída (ORS)

$ awk -F'*' '$1=="AK3"{ORS=OFS; print $2, $3} $1=="AK4"{ORS=RS; print $4, $5}' ip.txt
BPS 2 1 
RMT 12 7 CR
  • por padrão, o separador de campo de saída (OFS) é espaço único
  • e o separador de registro de entrada (RS) é nova linha

Isto é fácil de modificar para OFS diferente e também mostra um campo vazio

$ awk -F'*' -v OFS=',' '$1=="AK3"{ORS=OFS; print $2, $3} $1=="AK4"{ORS=RS; print $4, $5}' ip.txt
BPS,2,1,
RMT,12,7,CR
    
por 14.12.2017 / 16:21
0

Comum print adiciona uma nova linha (o separador de registro de saída), mas printf não, portanto, podemos usar isso no caso AK3 com um separador explícito entre os campos. No caso AK4 , queremos um separador de campo antes do primeiro campo, e a maneira mais simples de obter isso é imprimir um campo vazio primeiro.

$ awk -F\* '$1=="AK3" { printf "%s", $2 OFS $3 } $1=="AK4" { print "", $4, $5 }' < input 
BPS 2 1 
RMT 12 7 CR

Isso é facilmente convertido para dar saída com espaçamento de tabulação, basta adicionar -vOFS='\t' no início da linha de comando.

No entanto, se você quiser colunas com largura fixa, provavelmente será mais fácil usar as configurações printf e width no formato %s :

$ awk -F\* '$1=="AK3" { printf "%-3s %-2s", $2, $3 } $1=="AK4" { printf " %-1s %s\n", $4, $5 }' < input
BPS 2  1 
RMT 12 7 CR

Os campos extensos continuarão sendo estendidos, a menos que você também indique a largura máxima do campo, por exemplo, %-3.3s , e isso produzirá uma saída quebrada se as linhas de entrada não estiverem na ordem correta.

    
por 14.12.2017 / 16:11
0

Que tal:

awk -F '*' '{
    printf "%s %s", $2, $3
    getline
    for (i=4; i<=NF; i++) printf " %s", $i
    print ""
}' file | column -t
BPS  2   1
RMT  12  7  CR

Com o bash simples:

while IFS='*' read -r a1 b1 c1; IFS='*' read -r a2 b2 c3 rest
do
    echo "$b1 $c1 ${rest//\*/ }"
done < file
    
por 14.12.2017 / 16:54
0

Eu consegui o resultado abaixo dos comandos

sed -n '1~2p' testfile.txt| awk -F "*" '{print $2,$3}'  >> op.txt
sed -n '2~2p' testfile.txt | awk -F "*" '{print $4,$5}' >> op.txt

sed -n '1~2p' op.txt |sed "N;s/\n/ /g" |awk '{print $0"\n"}'; sed -n '2~2p' op.txt| sed "N;s/\n/ /g"

Saída

BPS 2 1

RMT 12 7 CR

por 14.12.2017 / 20:02