Я встретился с проблемой с подстановкой переменных в оболочке Bash.
Скажите определение переменной a
. Затем команда
$> echo ${a//[0-4]/}
печатает его значение со всеми числами, расположенными между 0 и 4 удаленных:
$> a="Hello1265-3World"
$> echo ${a//[0-4]/}
Hello65-World
Это, кажется, работает просто великолепно, но давайте смотреть на следующий пример:
$> b="你1265-3好"
$> echo ${b//[0-4]/}
你1265-3好
Замена не произошла: Я предполагаю, что это вызвано тем, что b
содержит символы CJK. Эта проблема расширяется на все случаи, в которые вовлечены квадратные скобки. Удивительно достаточно подстановка переменных без квадратных скобок хорошо работает в обоих случаях:
$> a="Hello1265-3World"
$> echo ${a//2/}
Hello165-3World
$> b="你1265-3好"
$> echo ${b//2/}
你165-3好
Действительно ли это - ошибка, или я пропускаю что-то?
Я использую Lubuntu 12.04, терминал lxterminal
и echo $BASH_VERSION
возвраты 4.2.24 (1) - выпуск.
Править: Andrew Johnson в его комментарии заявил это с gnome-terminal
4.2.37 (1) - выпускают команду, хорошо работает. Интересно, является ли это проблемой lxterminal
или ее определенного 4.2.24 (1) - версия выпуска.
Править: Я попробовал его gnome-terminal
на Lubuntu 12.04, но проблеме все еще там...
Короткий ответ:
набор LC_ALL=C для поведения Вы ожидаете
pauhel@permafrost:~$ b="你1265-3好"
paul@permafrost:~$ echo ${b//[0-2]/}
你1265-3好
paul@permafrost:~$ export LC_ALL=C
paul@permafrost:~$ echo ${b//[0-2]/}
你65-3好
Длинный ответ:
Поведение, которое Вы ожидаете, полагается на сопоставление, заказывающее, который является зависящей от реализации локалью/ОС. Стандарт POSIX оставляет это специфически неопределенным за исключением локали C. (Bash называет внешнюю библиотеку для этого и в предположении, похоже, что это отступает к ASCII, заказывающему, если только символы ASCII присутствуют).
Более поздние версии удара имеют опцию оболочки, которая позволяет Вам указать, что что-то как Вы ожидает.
См.:
https://groups.google.com/forum/#! topic/gnu.bash.bug/S6cN9KI4vK4/discussion
для большего количества фона.