![tr:將撇號轉換為 ASCII](https://rvso.com/image/977082/tr%EF%BC%9A%E5%B0%87%E6%92%87%E8%99%9F%E8%BD%89%E6%8F%9B%E7%82%BA%20ASCII.png)
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