如何使用sed修复经hd -c识别的特殊多字节连字符问题
特殊长连字符的批量替换问题
我有一个大文件c.txt,其中一行内容为:
7,VE,Bank–Charges
尝试执行如下命令替换连字符:
sed -i 's/-/ - /g' c.txt
期望得到的输出是:
7,VE,Bank – Charges
但该命令无效,文件中还有Vehicle–Maintenance这类包含特殊连字符的场景。
通过以下命令排查字符编码:
cat c.txt | head -n2 | tail -n1 | hd -c
得到输出:
00000000 37 2c 56 45 2c 42 61 6e 6b e2 80 93 43 68 61 72 |7,VE,Bank...Char| 0000000 7 , V E , B a n k 342 200 223 C h a r 00000010 67 65 73 0a |ges.| 0000010 g e s \n 0000014
由此确定,文件中的连字符是UTF-8编码的EN DASH(短破折号),对应字节为e2 80 93,而非普通ASCII短横线-(字节2d),这也是原sed命令无效的原因。
解决方案
1. 使用sed直接替换(推荐)
sed完全适用于该场景,有两种实现方式:
方式一:直接复制特殊字符写入命令
如果终端支持UTF-8,直接从文件中复制目标特殊连字符–,写入命令:
sed -i 's/–/ – /g' c.txt
方式二:通过字节转义匹配
如果无法直接输入特殊字符,可利用UTF-8字节编码转义匹配:
sed -i 's/\xe2\x80\x93/ – /g' c.txt
2. 使用awk处理
若担心不同环境下sed的UTF-8兼容性,可使用awk:
awk '{gsub(/–/, " – ")}1' c.txt > temp.txt && mv temp.txt c.txt
(现代awk版本默认支持UTF-8字符匹配,无需额外配置)
3. 其他工具说明
tr工具仅适用于单字符到单字符的映射替换,本次需求是将单个字符替换为空格+短横线+空格的组合,因此tr不适用。如果仅需将特殊连字符替换为普通短横线,可使用:tr '\xe2\x80\x93' '-' < c.txt > temp.txt && mv temp.txt c.txt
内容的提问来源于stack exchange,提问作者growler11
相关产品推荐
相关产品推荐

