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 использует 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?
4 ответа
Вы можете попробовать другой инструмент, например, 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
Если вы также хотите преобразовать двойные кавычки и, возможно, другие символы, вы можете использовать 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
не поддерживает это.
Вы можете использовать один из этих 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
Использование -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