Есть ли альтернатива 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
A-letubby
источник

Ответы:

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 для стандартного ввода, вывода и ошибки.

choroba
источник
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; но это не кажется необходимым.)

Janis
источник