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