tr命令是否修改文件编码?UTF-8文件特殊字符处理异常求助
解决UTF-8姓名列表中
tr命令搞乱特殊字符(如ç)的问题 嘿,这个坑我太熟了!你遇到的问题本质是**tr命令完全不支持多字节的UTF-8字符**——它会把每个字节当成独立的ASCII字符处理,而像ç这类特殊字符在UTF-8里是两个字节(0xC3 0xA7)组成的。当你用tr -d删元音时,要么是环境编码不一致,要么是tr误操作了其中一个字节,导致剩下的字节被解析成乱码(比如0xA7对应的就是ASCII里的§,你看到的xA7应该是转义后的显示)。
为什么tr不行?
举个实际例子:UTF-8的ç是C3 A7两个字节,tr只会逐个字节扫。如果你的元音列表里没包含这两个字节,理论上不该动它,但只要系统locale不是UTF-8,或者tr默认用了单字节模式,就会把多字节字符拆碎,结果就是乱码。而且tr从设计上就是给ASCII单字节字符用的,碰UTF-8必翻车。
靠谱的替代方案(支持UTF-8)
下面几种方法都能安全拆分辅音和元音,还能保留ç、ð、ñ这些特殊字符:
方法1:用支持UTF-8的sed
现在大部分Linux的sed都支持UTF-8(如果是老系统可以装gsed),直接匹配所有你提到的元音字符就行:
# 提取所有元音(带重音的也包含)到vowels.txt sed -E 's/[^àáâãæèéêëìíîïòóôõœùúûüýÿáéíóúýâêîôûãõñäëïöüÿçð]//g' input.txt > vowels.txt # 提取辅音(保留ç、ð、ñ等)到consonants.txt sed -E 's/[àáâãæèéêëìíîïòóôõœùúûüýÿáéíóúýâêîôûãõñäëïöüÿ]//g' input.txt > consonants.txt
[^...]是反向匹配:保留括号里的元音,删掉其他所有字符- 括号里把你提到的所有带重音元音都列全了,不会漏
- 辅音提取就是反过来,删掉所有元音,剩下的就是辅音
方法2:用awk(配UTF-8 locale)
先确保系统locale是UTF-8,然后用awk处理:
# 先设置locale,确保awk识别UTF-8 export LC_ALL=en_US.UTF-8 # 提取元音 awk '{ gsub(/[^àáâãæèéêëìíîïòóôõœùúûüýÿáéíóúýâêîôûãõñäëïöüÿçð]/, ""); print }' input.txt > vowels.txt # 提取辅音 awk '{ gsub(/[àáâãæèéêëìíîïòóôõœùúûüýÿáéíóúýâêîôûãõñäëïöüÿ]/, ""); print }' input.txt > consonants.txt
方法3:用grep拆分单个字符(每行一个)
如果想把每个字符单独拆出来(比如每行一个字符),用grep -o最方便:
# 提取所有元音字符(每行一个) grep -o '[àáâãæèéêëìíîïòóôõœùúûüýÿáéíóúýâêîôûãõñäëïöüÿçð]' input.txt > vowels.txt # 提取所有辅音字符(每行一个) grep -o '[bcdfghjklmnpqrstvwxzçðñ]' input.txt > consonants.txt
必看注意事项
- 先确认locale是UTF-8:执行
locale命令检查,如果不是,先跑export LC_ALL=en_US.UTF-8(或者你系统支持的其他UTF-8 locale) - 彻底放弃用
tr处理UTF-8文本:这工具就是为单字节设计的,碰多字节字符绝对出问题 - 先测小样本:拿包含
ç、ð、ñ的几行文本先试命令,确认输出没问题再处理整个文件
内容的提问来源于stack exchange,提问作者Gilalar
相关产品推荐
相关产品推荐

