从 unix 中的列内删除 csv 文件中的换行符
removing new line characters in csv file from inside columns in unix
示例输入数据::
cat test.csv
234,aa,bb,cc,30,dd
22,cc,
ff,dd,
40,gg
pxy,aa,,cc,
40
,dd
所需输出::
cat test_new.csv
234,aa,bb,cc,30,dd
22,cc,ff,dd,40,gg
pxy,aa,,cc,40,dd
我尝试了各种 awk
和 sed
命令,似乎没有任何效果。
例如::awk 'NR == 1{ printf [=14=]; next } { printf "%s%s", (/^[0-9]+,/? ORS : ""), [=14=] } END{ print "" }'
以上 awk
仅查找带有“,”的数字字符,但如果数字出现在带有换行符的列中,这将创建额外的行。
输入文件包含 Control M 字符,我已经使用 dos2unix 将其删除
关于“输入文件包含 Control M 字符,我已经使用 dos2unix 删除了这些字符”- 这可能会让您的生活更加艰难。很有可能一行中的“换行符”只是 LF
s 而记录结尾是 CRLF
因此通过删除 CR
s 我们不能再简单地设置 awk RS
到 CRLF
,然后删除记录中剩余的任何 LF
。
如果您的文件是从 Excel 导出的,正如您在问题下的评论中所说,那么无论字段是否被引用,它都会在每条记录的末尾使用 CRLF
,并且 LF
单独出现在每个字段中,如果您不在其上 运行 dos2unix
,则看起来像这样:
$ 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 的更多信息,请参阅 。
关于您的原始脚本 - 切勿使用 printf [=23=]
,始终使用 printf "%s", [=24=]
,因为当 [=25=]
包含任何 printf 格式字符(例如 %s
时,前者将失败:
$ echo 'a%sb' | awk '{printf "%s", [=13=]}'
a%sb$
$ echo 'a%sb' | awk '{printf [=13=]}'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`a%sb'
^ ran out for this one
$
这适用于对所有输入数据使用 printf
。
示例输入数据::
cat test.csv
234,aa,bb,cc,30,dd
22,cc,
ff,dd,
40,gg
pxy,aa,,cc,
40
,dd
所需输出::
cat test_new.csv
234,aa,bb,cc,30,dd
22,cc,ff,dd,40,gg
pxy,aa,,cc,40,dd
我尝试了各种 awk
和 sed
命令,似乎没有任何效果。
例如::awk 'NR == 1{ printf [=14=]; next } { printf "%s%s", (/^[0-9]+,/? ORS : ""), [=14=] } END{ print "" }'
以上 awk
仅查找带有“,”的数字字符,但如果数字出现在带有换行符的列中,这将创建额外的行。
输入文件包含 Control M 字符,我已经使用 dos2unix 将其删除
关于“输入文件包含 Control M 字符,我已经使用 dos2unix 删除了这些字符”- 这可能会让您的生活更加艰难。很有可能一行中的“换行符”只是 LF
s 而记录结尾是 CRLF
因此通过删除 CR
s 我们不能再简单地设置 awk RS
到 CRLF
,然后删除记录中剩余的任何 LF
。
如果您的文件是从 Excel 导出的,正如您在问题下的评论中所说,那么无论字段是否被引用,它都会在每条记录的末尾使用 CRLF
,并且 LF
单独出现在每个字段中,如果您不在其上 运行 dos2unix
,则看起来像这样:
$ 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 的更多信息,请参阅
关于您的原始脚本 - 切勿使用 printf [=23=]
,始终使用 printf "%s", [=24=]
,因为当 [=25=]
包含任何 printf 格式字符(例如 %s
时,前者将失败:
$ echo 'a%sb' | awk '{printf "%s", [=13=]}'
a%sb$
$ echo 'a%sb' | awk '{printf [=13=]}'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`a%sb'
^ ran out for this one
$
这适用于对所有输入数据使用 printf
。