![从 CSV 文件的列中删除换行符](https://linux22.com/image/196084/%E4%BB%8E%20CSV%20%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%97%E4%B8%AD%E5%88%A0%E9%99%A4%E6%8D%A2%E8%A1%8C%E7%AC%A6.png)
我们在 CSV 文件的一列中获取换行符。该列的数据位于连续的行中。例如:
ID,CODE,MESSAGE,DATE,TYPE,OPER,CO_ID
12202,INT_SYS_OCS_EX_INT-0000,"""OCSSystemException: HTTP transport error: java.net.ConnectException: Tried all: '1' addresses, but could not connect over HTTP to server: '10.244.166.9', port: '8080'
failed reasons:
[0] address:'/10.244.166.9',port:'8080' : java.net.ConctException: Connection refused
""",06-09-2021 05:52:32,error,BillCycle,6eb8642aa4b
20840,,,06-09-2021 16:17:18,response,changeLimit,1010f9ea05ff
问题在于列Message
和 id 12202 ,其中数据采用三引号且位于连续行中。
我的要求是,对于列Message
,数据应该出现在单行而不是多行中,因为我的 etl 加载器无法导入嵌入的换行符。
答案1
如果您的 CSV 是由 Excel 等 MS 工具生成的,则字段中间的“换行符”只是 LF,而每条记录末尾的“换行符”是 CRLF,如下所示(请注意 LF$
中字段与^M$
记录末尾的CRLF ):
$ cat -Ev file
ID,Code,Message,date^M$
1244,,"""Exception error : java connection error$
:8080 Connection refused""",01-09-2021^M$
如果是这样,您可以告诉 GNU awk(对于多字符 RS)记录以 CRLF 结尾,并用空格替换中间记录 LF:
$ awk -v RS='\r\n' '{gsub(/\n/," ")} 1' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021
如果您只有 POSIX awk 并且没有适用于 CSV 的工具,请参阅使用 awk 有效解析 csv 的最稳健方法是什么要了解如何处理它们,或者如果 CR 没有出现在文件中的其他位置,您可以使用任何 awk 执行此操作:
$ awk -v RS='\r' 'NR>1{print prev} {sub(/^\n/,""); gsub(/\n/," "); prev=$0}' file
ID,Code,Message,date
1244,,"""Exception error : java connection error :8080 Connection refused""",01-09-2021
答案2
一种简单的方法是删除只有 3 个字段的行上的换行符:
$ perl -F',' -pane 's/\n// if $#F==2' file
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,"ffadsdasd",01-09-2021
当然,这是假设您永远不能拥有,
内部字段,而 CSV 文件中允许这样做。因此,如果您的Message
字段包含类似的内容"""foo,bar"""
,它可能会失败。这就是为什么使用专用解析器总是更好的原因。
此方法适用于任何有效的 CSV 文件:
$ perl -MText::CSV -le '$csv = Text::CSV->new({binary=>1}); while ($row = $csv->getline(STDIN)){ $row->[2]=~s/\n//; $csv->print(STDOUT,$row)}' < file
ID,Code,Message,date
1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021
1245,,"""Exception error :""",01-09-2021
1246,,ffadsdasd,01-09-2021
答案3
答案4
第一步运行 CSV 文件并转换为 Unix 行结尾:
dos2unix your_csvfile
在下一步中这将更改为\r\n
“然后”:\n
使用 GNU sed 我们跟踪双引号的偶数/奇数,如下所示:
sed -Ee '
h;s/[^"]*//g
/^(..)*$/!{
z;G;N;D
}
g;s/\n//g
' your_csvfile
perl -pe 's/\n/<>/e while y/"// % 2' your_csvfile
我们可以使用 awk 实用程序来计算双引号的数量并不断累积行,直到它们变为偶数。
awk '{
t = $0
while ((gsub(/"/,"&",t) ~ /[13579]$/) && (getline nxt > 0))
t = t nxt
print t
}' your_csvfile
输出:
1 ID,Code,Message,date$
2 1244,,"""Exception error : java connection error:8080 Connection refused""",01-09-2021$