我有和这个完全相同的问题这里。唯一的区别是我只有 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