如何使用Unix命令去除CSV字段内的换行并合并内容?
嘿,我来帮你搞定这个CSV里字段被换行拆分的问题!
你的核心问题是带引号的字段内部包含换行符,导致原本的单行记录被拆成了多行,常规的按行处理工具会出错。之前的awk命令没成功,是因为你用的记录分隔符(RS)没有考虑引号的配对逻辑,没法正确识别完整的记录边界。
下面给你几个靠谱的解决方法,都能把处理后的内容输出到新文件里:
方法1:改进版awk命令(适合简单CSV场景)
这个命令会跟踪引号的状态,把引号内的换行符去掉,正确拼接完整记录:
awk -v OFS="," ' BEGIN { in_quote = 0 } { # 统计当前行的引号数量,切换引号内状态 n = gsub(/"/, "&", $0) in_quote += n % 2 # 拼接内容:在引号内时继续拼,否则处理后输出 line = line $0 if (!in_quote) { gsub(/\n/, "", line) # 去掉所有换行符,也可以换成" "保留空格 print line line = "" } } END { if (line != "") { gsub(/\n/, "", line); print line } } ' sample_attachments.csv > test.csv
- 原理:用
in_quote变量标记是否处于引号内部,只有当退出引号(引号数量为偶数)时,才处理并输出完整记录 - 如果希望字段内的换行换成空格而不是直接删除,把
gsub(/\n/, "", line)改成gsub(/\n/, " ", line)就行
方法2:Perl一行命令(简洁高效)
Perl的正则处理更灵活,能直接匹配引号内的内容并去除换行:
perl -0pe 's/"([^"]*)"/do { my $s = $1; $s =~ s/\n//g; "\"$s\""/ge' sample_attachments.csv > test.csv
-0参数让Perl把整个文件当作一个字符串读取,避免按行拆分的问题- 正则会匹配所有引号包裹的内容,把里面的换行符全部删除后再替换回去
方法3:Python脚本(最可靠,适合复杂CSV)
如果你的CSV存在转义引号(比如""表示一个引号)、字段内有逗号等复杂情况,用Python的标准csv模块是最稳妥的,它会严格遵循CSV规范:
import csv # 打开输入输出文件 with open('sample_attachments.csv', 'r', newline='', encoding='utf-8') as infile, \ open('test.csv', 'w', newline='', encoding='utf-8') as outfile: # 创建CSV读写器 reader = csv.reader(infile) writer = csv.writer(outfile) # 遍历每一行,清理每个字段里的换行符 for row in reader: cleaned_row = [field.replace('\n', '') for field in row] writer.writerow(cleaned_row)
这个方法几乎能处理所有CSV的边缘情况,推荐用于生产环境的复杂数据。
内容的提问来源于stack exchange,提问作者Chirag Raj
相关产品推荐
相关产品推荐

