BASH中变量替换与CJK字符之间的冲突
我在BASH shell中遇到了变量替换的问题。
假设你定义一个变量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) – echo $BASH_VERSION
。
编辑: 安德鲁约翰逊在他的评论中表示,使用gnome-terminal
4.2.37(1) – 发布命令工作正常。 我想知道这是lxterminal
还是其特定的4.2.24(1) – 发布版本的问题。
编辑:我在Lubuntu 12.04上尝试使用gnome-terminal
,但问题仍然存在……
简短回答:
设置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好
答案很长:
您期望的行为依赖于归类排序,这取决于区域设置/ OS实现。 除了C语言环境之外,POSIX标准使其特别未定义。 (Bash为此调用了一个外部库,并且,如果只有ASCII字符存在,它看起来会回到ASCII排序)。
更高版本的bash有一个shell选项,可以让你指定你期望的东西。
看到:
https://groups.google.com/forum/#!topic/gnu.bash.bug/S6cN9KI4vK4/discussion
了解更多背景资料