如何在Bash中将特定格式的文本文件稳健转换为CSV
如何在Bash中将特定格式的文本文件稳健转换为CSV
针对你的需求,我推荐用awk来处理——它在按行分组、处理特殊字符方面都很稳健,完全能满足你“除了空格和换行,值可以包含任意字符”的要求。
核心思路
你的输入是每4行构成一个数据组,组之间用空行分隔。我们需要忽略空行,把每组的4行用逗号连接成一行;同时如果值里包含逗号、双引号这类CSV敏感字符,还要按照CSV规范处理,避免生成不合法的文件。
最稳健的解决方案(awk命令)
awk 'NF { # 转义字段中的双引号:把单个双引号替换成两个(CSV规范要求) gsub(/"/, "\"\"", $0) # 将字段用双引号包裹,避免逗号等特殊字符破坏CSV结构 lines[++line_count] = "\"" $0 "\"" # 当攒够4行时,拼接成CSV行并输出 if (line_count == 4) { printf "%s,%s,%s,%s\n", lines[1], lines[2], lines[3], lines[4] line_count = 0 # 重置计数器,准备处理下一组 } } # 处理文件末尾可能存在的不完整组(如果有的话) END { if (line_count > 0) { output = lines[1] for (i=2; i<=line_count; i++) { output = output "," lines[i] } print output } }' input.txt > output.csv
命令详解
NF:只处理非空行(空行的字段数NF为0,会被跳过,正好匹配你组之间空行的格式)gsub(/"/, "\"\"", $0):按照CSV规范,字段里的双引号必须转义成两个双引号,否则会破坏CSV的结构lines[++line_count] = "\"" $0 "\"":把处理后的字段用双引号包裹后存入数组,这样即使字段里有逗号,也不会被当成CSV的分隔符- 当计数器到4时,用
printf把4个字段用逗号连接输出,然后重置计数器 END块:处理文件末尾可能存在的不足4行的组(如果你的输入是严格4行一组,这部分可以省略,但加上更稳健)
简洁但稍欠稳健的方案(paste命令)
如果你能确保值里绝对不会出现逗号、双引号这类CSV敏感字符,也可以用更简洁的paste命令,先过滤空行再每4行拼接:
grep -v '^$' input.txt | paste -d, - - - -
grep -v '^$'过滤掉所有空行,paste -d, - - - -表示用逗号作为分隔符,把连续的4行拼接成一行。这个方法快且简洁,但无法处理值里的特殊字符,生成的CSV可能不符合规范,只适合简单场景。
总结
优先推荐awk的方法,它兼顾了稳健性和对特殊字符的处理,完全符合你的需求。
备注:内容来源于stack exchange,提问作者Hashim Aziz
相关产品推荐
相关产品推荐

