And*_*asT 7 bash lubuntu utf-8 lxterminal
我在 BASH shell 中遇到了变量替换的问题。
假设您定义了一个变量a。然后命令
$> echo ${a//[0-4]/}
Run Code Online (Sandbox Code Playgroud)
打印其值,并删除所有介于 0 和 4 之间的数字:
$> a="Hello1265-3World"
$> echo ${a//[0-4]/}
Hello65-World
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,但让我们看看下一个例子:
$> b="?1265-3?"
$> echo ${b//[0-4]/}
?1265-3?
Run Code Online (Sandbox Code Playgroud)
没有发生替换:我认为这是因为b包含 CJK 字符。这个问题扩展到所有涉及方括号的情况。令人惊讶的是,没有方括号的变量替换在两种情况下都可以正常工作:
$> a="Hello1265-3World"
$> echo ${a//2/}
Hello165-3World
$> b="?1265-3?"
$> echo ${b//2/}
?165-3?
Run Code Online (Sandbox Code Playgroud)
这是一个错误还是我错过了什么?
我使用 Lubuntu 12.04,终端是lxterminal并echo $BASH_VERSION返回 4.2.24(1)-release。
编辑: 安德鲁约翰逊在他的评论中表示,使用gnome-terminal4.2.37(1)-release 命令可以正常工作。我想知道这是否是lxterminal其特定的 4.2.24(1)-release 版本的问题。
编辑:我gnome-terminal在 Lubuntu 12.04 上尝试过,但问题仍然存在......
小智 3
简短回答:
\n\n设置 LC_ALL=C 以获得您期望的行为
\n\npauhel@permafrost:~$ b="\xe4\xbd\xa01265-3\xe5\xa5\xbd"\npaul@permafrost:~$ echo ${b//[0-2]/}\n\xe4\xbd\xa01265-3\xe5\xa5\xbd\npaul@permafrost:~$ export LC_ALL=C\npaul@permafrost:~$ echo ${b//[0-2]/}\n\xe4\xbd\xa065-3\xe5\xa5\xbd\nRun Code Online (Sandbox Code Playgroud)\n\n长答案:
\n\n您期望的行为依赖于排序规则,而排序规则取决于语言环境/操作系统实现。除 C 语言环境外,POSIX 标准未明确定义它。(Bash 为此调用一个外部库,据猜测,如果仅存在 ASCII 字符,则看起来会回退到 ASCII 排序)。
\n\nbash 的更高版本有一个 shell 选项,可以让您指定您期望的内容。
\n\n看:
\n\nhttps://groups.google.com/forum/#!topic/gnu.bash.bug/S6cN9KI4vK4/discussion
\n\n了解更多背景。
\n