Como iniciar uma nova linha a cada enésima coluna?

1

Portanto, tenho um arquivo de texto com 20.000 "colunas" longas e duas linhas. Dados parecem com algo assim:

  FP1 amp     FP1 lat     FP2 amp       FP2 lat    FP3 amp       FP3 lat      AF1 amp         AF1 lat 
  4.1         231         2.2           232        1.3            233         4.4             234

A cada 120 colunas, os valores do cabeçalho se repetem com valores diferentes na segunda linha. Como posso separar essas "colunas" a cada 120 colunas, iniciar uma nova linha e continuar fazendo isso até o final do arquivo?

    
por user186549 25.08.2016 / 21:39

1 resposta

1

Suponha que transponhamos os dados com BSD rs :

$ rs -T
a b c d e f g h
1 2 3 4 5 6 7 8
[Ctrl-D][Enter]
a  1
b  2
c  3
d  4
e  5
f  6
g  7
h  8

Agora, temos duas colunas longas, suscetíveis a awk de processamento. Podemos varrer os dados e acumular um par de strings de $1 e $2 . Sempre que NR modulo o tamanho de linha desejado é zero, nós geramos as strings acumuladas.

$ awk '{ hdrs = (hdrs ? hdrs OFS $1 : $1);
         vals = (vals ? vals OFS $2 : $2); }
       !(NR % 3) { print hdrs; print vals;
                   hdrs = vals = "" } 
       END { print hdrs; print vals; }'
a  1
b  2
c  3
d  4
e  5
f  6
g  7
h  8
[Ctrl-D][Enter]
a b c
1 2 3
d e f
4 5 6
g h
7 8

Se for necessária uma forma de saída diferente, como a seguinte (cabeçalhos e valores embalados individualmente, em um padrão congruente), não é difícil massagear isso do código Awk:

a b c
d e f
g h
1 2 3
4 5 6
7 8

Agora, os dados reais são confusos porque têm títulos de campos delimitados por vários espaços e contêm espaços próprios.

Supondo que os campos contenham apenas espaços internos únicos e estejam sempre separados por espaços múltiplos, o que podemos fazer é pré-processar os dados para substituir os espaços internos por um caractere que não seja espaço em branco (isso já não ocorre nos dados ), como um til ( ~ ). Por exemplo, usando Sed:

$ sed -e 's/\([^ ]\) \([^ ]\)/~/g'
foo bar      xyzzy quux      alpha beta     gamma     delta
[Ctrl-D][Enter]
foo~bar      xyzzy~quux      alpha~beta     gamma     delta

Filtrar de volta é fácil com

tr '~' ' '
    
por 02.09.2016 / 07:29