tr:将撇号转换为ASCII


11

我想一个转换右单引号一个撇号使用tr

tr "`echo -e '\xE2\x80\x99'`" "`echo -e '\x27'`" < a > b

给定一个名为UTF-8编码的文件a,其中包含以下示例:

Were not a different species
All alone?” Jeth mentioned.

OS X使用BSD tr并产生不错的结果:

We're not a different species
“All alone?” Jeth mentioned.

Ubuntu使用GNU tr并产生以下讨厌的结果:

We'''re not a different species
''<9C>All alone?''<9D> Jeth mentioned.

如何在Ubuntu中完成此转换?


也尝试过:tr $'\ xE2 \ x80 \ x99'$'\ x27'<a> b,结果相同。
plamtrue 2014年

1
这是好事,知道ASCII和Unicode引号
αғsнιη

2
echo It’s easy | perl -CS -Mutf8 -pe "tr/’/'/"
tchrist

Answers:


16

您可以尝试其他一些工具,例如sed

$ sed "s/’/'/g" <a
We're not a different species
“All alone?” Jeth mentioned.

或者,由于我们正在执行简单的翻译,因此可以将y命令用于sed

$ sed "y/’/'/" <a
We're not a different species
“All alone?” Jeth mentioned.

GNUtr不能正常工作是因为:

当前tr仅完全支持单字节字符。最终它将支持多字节字符;当它-C 启用时,该选项将使它补充字符集,而使-c 它对值集补充。仅当某些值不是字符时,这种区分才重要;只有当输入包含编码错误时,才可能在使用多字节编码的语言环境中实现。

并且是一个多字节字符:

$ echo -n \' | wc -c
1
$ echo -n  | wc -c  
3

1
sed这类工作要好得多。
Kaz Wolfe 2014年

2
为了解释的最后部分进一步:tr与分别替换各三个字节的',因此,'''以及其中它取代二在类似字符三个字节的破碎序列。相反,它应该将三个字节理解为一个字符,并替换它。
2014年

很好理解的是一个多字节字符,我们还可以使用tr -c '[:print:][:cntrl:]' '-'command将一个非打印字符(有效控制字符除外)替换为-。并且您会看到将单个翻译转换为3个字节的字符,例如---。多字节字符的好处。
αғsнιη

9

如果您还想转换双引号和其他字符,可以使用GNUiconv

$ iconv -f utf-8 -t ascii//translit < a
We're not a different species
"All alone?" Jeth mentioned.

所述//TRANSLIT后缀告诉iconv,对于目标编码(这里ASCII)的剧目以外的字符,它可以自动替代外观相似的字符或序列。如果没有后缀,iconv则会在发现不可翻译的字符时立即放弃。

请注意,这//TRANSLIT似乎是GNU扩展:POSIXiconv不支持它。


+1。如果要将文本从一种字符集(或编码)转换为另一种字符集,则可以使用为此目的而设计的工具。
RedGrittyBrick 2014年

@deltab您的解决方案还替换了OP不想替换的双引号。
αғsнιη

@KasiyA也许他们应该。
gerrit 2014年

3

您可以使用以下awk解决方案之一:

awk '{gsub(/\xE2\x80\x99/, "\x27");print}' file # with Hex ASCII code

awk '{gsub(/’/, "\x27");print}' file

awk '{gsub(/\342\200\231/, "\47");print}'  file # with Octal ASCII code

awk '{gsub(/’/, "\47");print}' file

要么

awk '{gsub(/’/, "'"'"'");print}' file

0

使用-s选项tr :

$ echo "We’re not a different species"|tr -s "’" "'"
We're not a different species

来自man tr :

--truncate-set1
          first truncate SET1 to length of SET2

1
您的解决方案也取代了OP不想取代他们的双引号
αғsнιη

啊,确实,谢谢你指出这一点。我将这个答案留作参考。
Skippy le Grand Gourou 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.