使用 awk 切换 CSV 中的列?

使用 awk 切换 CSV 中的列?

我有和这个完全相同的问题这里。唯一的区别是我只有 3 列,我试图将第一列移到最后。

原始文件如下所示:

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

我没有犯其他提问者所犯的错误(即没有在 F 或 OFS= 之后添加逗号)。所以,我的代码是

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

但我在新行中得到了第三列(曾经是第一列):

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

为什么 awk 将第三列数据发送到新行?我在 Windows 上的 Linux Bash Shell (Ubuntu) 上使用 awk,从以下位置下载这里

答案1

您的输入文件中似乎包含一些额外数据,例如,DOS 样式的换行符 ( \r\n),而在 Unix 系统上,文件通常只有\n

例如:

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

我们可以使用hexdump查看该文件的实际 ASCII:

$ 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

请注意,0a在十六进制输出中,这是一个换行符 ( \n)。如果我基本上使用你的awk这个文件,它会按预期工作:

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

如果我们old.csv使用 CLI 工具将该文件转换为通常形成 Windows/DOS 系统的文件,则unix2dos修改后的文件old_dos.csv将如下所示:

$ 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

现在我们看到0d&0a是一个\r\n.awk在此文件上使用的行为很奇怪:

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

相关内容