tr: конвертировать апостроф в ASCII


11

Я пытаюсь преобразовать правую одинарную кавычку в апостроф с помощью 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?


Также пробовал: tr $ '\ xE2 \ x80 \ x99' $ '\ x27' <a> b с такими же результатами.
— plamtrue

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намного лучше для такой работы.
— Каз Вулф

2
Чтобы пояснить последнюю часть далее: trзаменяется каждый из трех байтов отдельно на ', следовательно, '''также на прерывистые последовательности, где он заменил два из трех байтов аналогичными символами “и ”. Вместо этого следует понимать, что три байта означают один символ, и заменить его вместо этого.
— Deltab

Для лучшего понимания ’это многобайтовый символ, также мы можем использовать tr -c '[:print:][:cntrl:]' '-'команду для замены любого непечатаемого символа , кроме допустимых управляющих символов, на -. И вы увидите один ’перевод до 3 байтов символов, как ---. хорошая точка для многобайтового символа.
— 2014 г.

9

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


+1. Если вы конвертируете текст из одного набора символов (или кодировки) в другой, может быть целесообразно использовать инструмент, разработанный для этой цели.
— RedGrittyBrick

@deltab ваше решение также заменяет двойные кавычки, которые OP не хочет их заменять.
— αғsнιη

@KasiyA Может быть, они должны.
— gerrit

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 не хочет их заменять
— αғsнιη

Ах, действительно, спасибо за указание на это. Я оставлю этот ответ для справки.
— Скиппи ле Гран Гуру
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.