如何用Linux命令替换非ASCII字符及非管道前后的双引号?
处理带特殊字符的分隔符CSV文件问题
我有一批以|为分隔符的CSV文件,部分字符串字段被双引号包裹。这些字段包含人工添加的注释,存在非ASCII(Unicode)字符和字面双引号,导致数据加载流程异常。需要完成两个处理目标:
- 移除所有非ASCII字符
- 删除所有不紧邻
|的双引号
示例
输入内容:
SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 ""¬PID35032 â¿""" AWS Migration""|0000
期望输出:
SEP-23|3958|106xxx|Anonymous Account||IE - IT|000|000000|000|DEFAULT|"TI805 PID35032 AWS Migration"|0000
之前的尝试
曾使用以下sed命令,但需要多次执行,且当前场景下失效,怀疑与非ASCII字符有关:
sed -i 's/\([^|]\)"\([^|]\)/\1\2/g' sample.csv
解决方案
方法1:使用awk(推荐)
awk能更精准地按字段处理,一次性完成两个需求:
awk -F'|' -v OFS='|' '{ for(i=1; i<=NF; i++) { # 移除所有非ASCII字符 gsub(/[^\x00-\x7F]/, "", $i) # 处理双引号:保留字段首尾的引号,清除中间所有引号 if ($i ~ /^".*"$/) { sub(/^"/, "", $i) sub(/"$/, "", $i) gsub(/"/, "", $i) $i = "\"" $i "\"" } else { gsub(/"/, "", $i) } } print $0 }' sample.csv > cleaned_sample.csv
命令说明:
-F'|' -v OFS='|':指定输入、输出的字段分隔符均为|- 遍历每个字段:
gsub(/[^\x00-\x7F]/, "", $i):剔除字段中所有超出ASCII范围(0-127)的字符- 针对带引号的字段,先剥离首尾引号、清除内部所有引号,再重新包裹首尾引号;不带引号的字段直接清除所有引号
- 处理完成后输出整行内容到新文件
方法2:使用GNU sed
如果偏好sed,可使用以下命令(需GNU sed支持Unicode处理):
sed -i -E ' # 先移除所有非ASCII字符 s/[^\x00-\x7F]//g; # 循环删除所有不紧邻|的双引号,直到无匹配项 :loop s/(^|[^|])"([^|]|$)/\1\2/g t loop ' sample.csv
命令说明:
- 先清除所有非ASCII字符,避免干扰后续引号匹配
- 通过
:loop和t loop实现循环替换,解决原命令需多次执行的问题 - 匹配所有不在
|两侧的双引号并删除
内容的提问来源于stack exchange,提问作者Sergio Jimenez
相关产品推荐
相关产品推荐

