Alterna colunas em CSV usando o awk? [duplicado]

1

Eu tenho exatamente a mesma pergunta que esta aqui . A única diferença é que tenho apenas 3 colunas e estou tentando mover a primeira coluna para o final.

O arquivo original é assim:

col1,col2,col3
2,2015-01-04,23
196,2015-01-20,36

Eu não cometi o erro que outro questionador fez (ou seja, não colocar vírgula após F ou após OFS =). Então, meu código é

awk -F, '{print $2,$3,$1}' OFS=, old.csv > new.csv

Mas estou recebendo a terceira coluna (que costumava ser a primeira) em uma nova linha:

col1,col2,col3
2015-01-04,23
,2
2015-01-20,36
,196

Por que o awk está enviando os dados da terceira coluna para uma nova linha? Estou usando o awk no Linux Bash Shell (Ubuntu) no Windows, baixado de aqui .

    
por ahmed_m 08.08.2018 / 01:36

1 resposta

2

Parece que seu arquivo de entrada possui alguns dados adicionais, como as novas linhas de estilo DOS ( \r\n ), enquanto que, normalmente, em sistemas Unix, os arquivos possuem apenas \n .

Por exemplo:

$ cat old.csv
col1,col2,col3
2,2015-01-04,23
196,2015-01-20,36

Podemos usar hexdump para ver o ASCII real desse arquivo:

$ hexdump -C old.csv
00000000  63 6f 6c 31 2c 63 6f 6c  32 2c 63 6f 6c 33 0a 32  |col1,col2,col3.2|
00000010  2c 32 30 31 35 2d 30 31  2d 30 34 2c 32 33 0a 31  |,2015-01-04,23.1|
00000020  39 36 2c 32 30 31 35 2d  30 31 2d 32 30 2c 33 36  |96,2015-01-20,36|
00000030  0a                                                |.|
00000031

Observe o 0a na saída HEX, esta é uma nova linha ( \n ). Se eu usar basicamente seu awk com este arquivo, ele funciona como esperado:

$ awk -F, '{print $2,$3,$1}' OFS=, old.csv
col2,col3,col1
2015-01-04,23,2
2015-01-20,36,196

Se convertermos o arquivo old.csv em um que normalmente forma um sistema Windows / DOS usando uma ferramenta CLI unix2dos do arquivo modificado, old_dos.csv se parece com isto:

$ hexdump -C old_dos.csv
00000000  63 6f 6c 31 2c 63 6f 6c  32 2c 63 6f 6c 33 0d 0a  |col1,col2,col3..|
00000010  32 2c 32 30 31 35 2d 30  31 2d 30 34 2c 32 33 0d  |2,2015-01-04,23.|
00000020  0a 31 39 36 2c 32 30 31  35 2d 30 31 2d 32 30 2c  |.196,2015-01-20,|
00000030  33 36 0d 0a                                       |36..|
00000034

Agora vemos 0d & 0a , que é \r\n . Usar awk nesse arquivo age de maneira estranha:

$ awk -F, '{print $2,$3,$1}' OFS=, old_dos.csv
,col1col3
,215-01-04,23
,196-01-20,36
    
por 08.08.2018 / 03:23