Есть ли альтернатива sed, поддерживающая юникод?


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
Считается ли 馑 как один символ или 3? То есть echo 馑 | sed s/...//печатает что-нибудь?
user253751

@immibis Так как sedимеет модификатор g, он заменяет все вхождения, даже когда они следуют друг за другом. Также sed должен считать это как один символ, см .: echo -ne "馑" | wc -mдает 1. Если вы посчитаете bytes ( wc -c), он вернется 3. Правильно ли я понял ваш вопрос?
хаос

Я имел в виду: .означает «один символ» или «один байт»?
user253751

@immibis Я соответствую одному символу, следовательно, echo 馑 | sed s/...//дает мне (ничто не заменяется)
хаос

4
@chaos: работает под en_US.UTF-8, но не под C.
Чороба

15

Perl может сделать это:

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

-CS включает UTF-8 для стандартного ввода, вывода и ошибки.


7
Perl может делать практически все, что угодно .....
wobbily_col

6

Ряд версий sedподдержки Unicode :

  • Семейная реликвия sed , в основе которой лежит «оригинальный материал Unix».
  • GNU sed , которая является собственной кодовой базой.
  • Plan 9 sed , которая была портирована на Unix-подобные операционные системы.

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


Они поддерживают UTF-16 с и без спецификации?
Бон Ами

10
UTF-16 довольно непригоден для Unix-систем. Это также мерзость, которую никогда не должен был видеть дневной свет.
Брайан Би

Поддерживают ли они UTF-16, зависит от реализации, и я боюсь, что у меня нет этих данных. Я сомневаюсь, что Plan 9 Sed (оригинальная ОС везде UTF-8), но я не уверен, и даже если это не так, другие могут.
Самая ложная

2

Это работает для меня:

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

Это капля более многословная, чем мне бы хотелось; вот полное объяснение:

  • -n отключить файл подкачки vim
  • -E Ex улучшенный режим
  • -s бесшумный режим
  • +'%s/\%u9991//g' выполнить команду замещения
  • +wq Сохранить и выйти

Я предполагаю, что это изменяет file1 на месте , это правильно?
Геррит

@gerrit это правильно, и спасибо за указание на это.
Арье Лейб Таурог

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.