tr:將撇號轉換為 ASCII

tr:將撇號轉換為 ASCII

我正在嘗試轉換右單引號到一個撇號使用tr

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

給定一個名為 UTF-8 編碼的文件a,其中包含以下範例:

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

OS X 使用 BSDtr並產生了不錯的結果:

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

Ubuntu 使用 GNUtr並產生了這個令人討厭的結果:

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

我怎麼能在Ubuntu中完成這個轉換?

答案1

您可以嘗試其他一些工具,例如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

答案2

如果您還想轉換雙引號以及其他字符,您可以使用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不支援。

答案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

答案4

使用-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

相關內容