sed regexp ПРЕОБРАЗОВЫВАЮТ символ в шестнадцатеричную систему

С zsh:

$ autoload zmv
$ zmv -v '(*)(??)(??)(??).avi' '$1\:$2\:$3\:$4.avi'
mv -- custom\ text\ 00030402.avi custom\ text\ 00\\:03\\:04\\:02.avi

(-v для подробного). Удалить пользовательский текст:

$ zmv -v '*(??)(??)(??)(??).avi' '$1\:$2\:$3\:$4.avi'
mv -- custom\ text\ 00030402.avi 00\\:03\\:04\\:02.avi
3
16.04.2018, 16:40
1 ответ

Это потому, что [...] совпадает по символу. sed пытались бы сопоставить символы с диапазоном, указанным в [...]. В локалях UTF-8 можно встретить только \x8f как часть многобайтового символа. Вы заметите, что . на нем тоже не совпадает (и это требование POSIX).

Например:

sed 's/[eé\xa9]//'

не имеет смысла. é - символ (закодированный как 0xa9), 0xa9 - не символ, а байт, может быть найден внутри символа (как é), e - символ (закодированный как 0x65). Вы не можете ожидать, что sed каким-то образом сможет соответствовать 0xa9 как внутри символа, так и в виде байта.

Чтобы сопоставить произвольные данные байта с утилитой text, такой как sed, вы захотите использовать локаль, где символы - это байты, это типичный случай для LC_ALL=C.

LC_ALL=C sed 's/12[\x8f\x9f]//g'

Или portably:

LC_ALL=C sed "$(printf 's/12[\217\237]//g')"

Обратите внимание, что вы не можете ожидать обработки данных, содержащих символы NUL (или которые не заканчиваются символом новой строки, или где символы новой строки больше, чем несколько килобайт appart) portably с помощью sed. Вместо этого используйте perl -p/-n.

.
7
27.01.2020, 21:12

Теги

Похожие вопросы