Чи є альтернатива sed, який підтримує unicode?


33

Наприклад:

sed 's/\u0091//g' file1

Зараз я маю зробити, hexdumpщоб отримати шістнадцятковий номер і ввести sedнаступне:

$ echo -ne '\u9991' | hexdump -C
00000000  e9 a6 91                                          |...|
00000003

І потім:

$ sed 's/\xe9\xa6\x91//g' file1

Відповіді:


28

Просто використовуйте цей синтаксис:

sed 's/馑//g' file1

Або у втеченому вигляді:

sed "s/$(echo -ne '\u9991')//g" file1

(Зауважте, що старіші версії Bash та деяких оболонок не розуміють echo -e '\u9991', тому спочатку перевірте.)


1
Чи вважає sed 馑 одним символом або 3? Тобто чи echo 馑 | sed s/...//друкує щось?
користувач253751

@immibis Оскільки sedмодифікатор g має місце, він замінює всі випадки, коли вони слідують один за одним. Також sed слід вважати це одним символом, див .: echo -ne "馑" | wc -mдає 1. Якщо порахувати байти ( wc -c), він повернеться 3. Чи правильно я зрозумів ваше запитання?
хаос

Я мав на увазі: чи .означає "один символ" чи "один байт"?
користувач253751

@immibis Я збігається з одним персонажем, тому echo 馑 | sed s/...//дає мені (нічого не замінено)
хаос

4
@chaos: працює під en_US.UTF-8, але не під C.
choroba

15

Perl може це зробити:

echo 汉典“馑”字的基本解释 | perl -CS -pe 's/\N{U+9991}/Jin/g'

-CS вмикає UTF-8 для стандартного введення, виводу та помилки.


7
Perl може зробити майже все, що завгодно .....
wobbily_col

6

Ряд версій sedпідтримки Unicode :

  • Heirloom sed , в основі якого лежить "оригінальний матеріал Unix".
  • GNU sed , яка є власною базою кодів.
  • План 9 sed , який був перенесений на Unix-подібні операційні системи.

Я не міг знайти інформацію про BSD sed, що мені здалося дивним, але я думаю, що шанси добре, що він підтримує і Unicode. На жаль, не існує стандартного способу сказати, sedяке кодування використовувати, тому кожен робить це по-своєму.


Чи підтримують вони UTF-16 з та без BOM?
Бон-Амі

10
UTF-16 досить непридатний для використання на ОС Unix. Це також гидота, яка ніколи не повинна побачити світло дня.
Брайан Бі

Чи підтримують вони UTF-16 чи ні, залежить від впровадження, і, боюся, у мене немає цих даних. Я сумніваюся, що план 9 sed (оригінальна ОС скрізь є UTF-8), але я не можу бути впевнений, і навіть якщо це не так, інші можуть.
Найгучніший

2

Це працює для мене:

$ vim -nEs +'%s/\%u9991//g' +wq file1

Це крапля більш багатослівна, ніж я хотів би; ось повне пояснення:

  • -n вимкнути файл swap vim
  • -E Ex вдосконалений режим
  • -s Режим тиші
  • +'%s/\%u9991//g' виконати команду підстановки
  • +wq зберегти та вийти

Я припускаю, що це змінюється file1 на місці , це правильно?
Герріт

@gerrit це правильно, і дякую, що вказали на це.
Aryeh Leib Taurog

1

У останніх версіях BASH просто опустіть лапки навколо виразу sed і ви можете використовувати втечені рядки BASH. Проміжки в межах експресії sed або частини експресії sed, які можуть бути інтерпретовані BASH як макіяж, можуть бути окремо цитовані.

$ echo "饥馑荐臻" | sed s/$'\u9991'//g
饥荐臻

Це має бути нова прийнята відповідь, проста та чиста!
Аллен Ван

0

Для мене працює GNU sed (версія 4.2.1):

$ echo -ne $'\u9991' | sed 's/\xe9\xa6\x91//g' | hexdump -C
$ echo -ne $'\u9991' | hexdump -C
00000000  e9 a6 91

(В якості іншої заміни sedви також можете використовувати GNU awk; але це не здається необхідним.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.