AWK fundindo as linhas

0

Eu tenho um arquivo de entrada como abaixo

1
2
3
4
5
6
7
8
9
10

Eu preciso de uma saída como abaixo

1 2
3 4 5
6 7
8 9 10

Significado primeiro duas linhas a serem unidas e, em seguida, as próximas três linhas para ser também unidas.

    
por Nithin Kumar 05.01.2018 / 19:19

4 respostas

0

Uma abordagem dupla do awk:

$ awk '{printf("%s",$0 (NR%5==0?ORS:":"))}' file1 |awk -F':' '{print $1,$2;print $3,$4,$5}'
1 2
3 4 5
6 7
8 9 10

As linhas são unidas pela primeira vez em grupos de cinco, cada linha associada ao símbolo : .

O trabalho da solução, mesmo que as linhas contenham mais palavras

$ cat file2
this is line 1
this is line 2
this is line 3
this is line 4
this is line 5
this is line 6
this is line 7
this is line 8
this is line 9
this is line 10

$ awk '{printf("%s",$0 (NR%5==0?ORS:":"))}' file2 |awk -F':' '{print $1,$2;print $3,$4,$5}'
this is line 1 this is line 2
this is line 3 this is line 4 this is line 5
this is line 6 this is line 7
this is line 8 this is line 9 this is line 10
    
por 06.01.2018 / 10:51
2

Eu também posso fazer o trabalho com paste :

$ seq 10 | paste -s -d $' \n  \n'
1 2
3 4 5
6 7
8 9 10
$ 

bash foi usado por mim aqui (por $'\n' ). E seq 10 foi para reproduzir sua entrada:

$ seq 10
1
2
3
4
5
6
7
8
9
10
$
    
por 06.01.2018 / 10:07
1
#!/usr/bin/awk -f

BEGIN { maxlines=2 ; lc=0 }

{ outputline=outputline " " $0; lc++ }

lc % maxlines == 0 {
  sub(/^ /,"",outputline); # strip unwanted leading space
  print outputline;

  outputline="";
  lc=0;
  maxlines = 5 - maxlines; # flip-flop: 5-2=3, 5-3=2
}

Isto alterna entre juntar & imprimindo 2 ou 3 linhas consecutivas.

Saída:

1 2
3 4 5
6 7
8 9 10

ou com os dados de entrada originais:

Unix Linux
Solaris AIX Sco

Como alternativa, usando uma matriz. awk não tem uma função join() , então temos que fornecer uma.

#!/usr/bin/awk -f

BEGIN { maxlines=2 ; lc=0 }

function join(sep,array,       i) {
  result=array[1];
  for (i=2;i<=length(array);i++) result = result sep array[i];
  return result
};

{ lines[++lc]=$0 }

lc % maxlines == 0 {
  print join(" ", lines);
  delete lines;

  lc=0;
  maxlines = 5-maxlines
}
    
por 06.01.2018 / 05:46
0

Basta fazer o trabalho abaixo de awk :

awk -v step=3 '{l=(!l)?l$0:l" "$0} ++seen==2 && step==3{print l;step++;l=seen=""}
    seen==3{print l;step--;l=seen=""}' infile

Saída:

1 2
3 4 5
6 7
8 9 10
    
por 06.01.2018 / 07:24

Tags