tr:アポストロフィをASCIIに変換します


11

を使用して、右単一引用符アポストロフィに変換しようとしていtrます。

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

aこの例を含むと呼ばれるUTF-8エンコードされたファイルが与えられた場合:

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 14年

1
これは知って良いですASCIIおよびUnicodeの引用符
αғsнιη

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

回答:


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この種の作業にははるかに適しています。
カズウルフ14

2
最後の部分をさらに説明するtrと、3バイトのそれぞれを'で個別に'''置き換えているため、同様の文字との3バイトのうち2つを置き換えた壊れたシーケンスです。代わりに、3バイトが一緒になって1文字を意味するものとして理解し、代わりにそれを置き換える必要があります。
deltab

マルチバイト文字を理解するために、tr -c '[:print:][:cntrl:]' '-'コマンドを使用して、有効な制御文字以外のすべての非印刷文字を-。そして、のような3バイトの文字への単一の翻訳が表示されます---。マルチバイト文字に適しています。
αғsнιη

9

二重引用符やその他の文字も変換したい場合は、GNUをiconv使用できます。

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

//TRANSLITサフィックスは伝えiconvターゲットエンコーディング(ここではASCII)のレパートリー外の文字のために、それが自動的に類似した文字やシーケンスを置き換えることができること。接尾辞がなければ、iconv翻訳できない文字が見つかるとすぐにgiveめます。

これ//TRANSLITはGNU拡張機能のように見えることに注意してください。POSIXiconvはサポートしていません。


+1。ある文字セット(またはエンコード)から別の文字セットにテキストを変換する場合、その目的のために設計されたツールを使用するのが賢明です。
RedGrittyBrick 14年

@deltabは、OPがそれらを置き換えたくない二重引用符もソリューションで置き換えます。
αғsнιη

@KasiyAたぶん彼らはすべきです。
ジェリット14年

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がそれらを置き換えたくない二重引用符も置き換えます

ああ、これを指摘してくれてありがとう。参照用にこの回答を残します。
スキッピールグラングロウ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.