关于“输入文件包含 Control M 字符,我已经使用 dos2unix 删除了” - 这可能会让您的生活变得更加困难。一行中的“换行符”很可能只是LF
s 而记录结尾是CRLF
所以通过删除CR
我们不能再简单地设置 awkRS
to CRLF
然后删除任何LF
s 仍保留在记录中。
如果您的文件是从 Excel 导出的,正如您在问题下的评论中所说,那么无论字段是否被引用,它都会使用CRLF
在每条记录的末尾,以及LF
单独在每个字段中,如果你不运行的话,看起来像这样dos2unix
on it:
$ cat -v test.csv
234,aa,bb,cc,30,dd^M
22,cc,
ff,dd,
40,gg^M
pxy,aa,,cc,
40
,dd^M
然后使用任何 awk:
$ awk -v ORS= '{sub(/\r$/,"\n")} 1' test.csv
234,aa,bb,cc,30,dd
22,cc,ff,dd,40,gg
pxy,aa,,cc,40,dd
或者,如果您愿意,可以使用 GNU awk 进行多字符 RS:
$ awk -v RS='\r\n' '{gsub(/\n/,"")} 1' test.csv
234,aa,bb,cc,30,dd
22,cc,ff,dd,40,gg
pxy,aa,,cc,40,dd
有关使用 awk 解析 CSV 的更多信息,请参阅使用 awk 有效解析 CSV 的最可靠方法是什么? https://stackoverflow.com/questions/45420535/whats-the-most-robust-way-to-efficiently-parse-csv-using-awk.
关于你的原始脚本 - 永远不要使用printf $0
,始终使用printf "%s", $0
相反,因为前者会失败$0
包含任何 printf 格式字符,例如%s
:
$ echo 'a%sb' | awk '{printf "%s", $0}'
a%sb$
$ echo 'a%sb' | awk '{printf $0}'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`a%sb'
^ ran out for this one
$
这适用于使用printf
对所有输入数据。