我认为 bash 变量替换和通配符起作用特点分辨率,所以我很惊讶地看到它在字节等级。
我的一切locale
都是 en_AU.UTF-8
当没有任何内容可以匹配并且模式允许零到多时,替换发生在字节水平,如随后的替换所示。我原以为它会移动到下一个特点,但它并不...
也许这只是一个奇怪的边缘案例模式,或者我错过了一些明显的东西,但我确实想知道这里发生了什么,除了这个特定模式之外,我可以在其他地方期待这种行为吗?
这是脚本(最初是尝试将字符串拆分为字符)。
我预计最后一次测试,对于 character ळ
,最终只会得到一个单身的前面有空格ळ
,但字符的 3 个 UTF-8 字节前面各有一个空格。这会导致无效的 UTF-8 输出。
shopt -s extglob
for str in $'\t' "ab" ळ ;do
printf -- '%s' "${str//*($'\x01')/ }" |xxd
done
输出:
0000000: 2009 .
0000000: 2061 2062 a b
0000000: 20e0 20a4 20b3 . . .
答案1
您的问题的简短答案是 *(pattern-list) 将匹配给定模式的零次或多次出现。每个输入字节之间有零个 Unicode 字符 0001 实例。因此,替换操作将这零个实例中的每一个替换为一个空格。
也许你想这样做:
$ for str in $'\t' "ab" ळ ; do
printf -- '%s' "${str//+($'\x01')/ }" |xxd
done)
0000000: 09 .
0000000: 6162 ab
0000000: e0a4 b3 ...
但更长的答案是,无论如何,路径名都不是文本。至少,就(类 Unix)操作系统而言,它们还不够。它们是字节序列。问题是这样的事情做起来很简单:
$ LC_ALL=latin1
$ mkdir 'áñ' && cd 'áñ'
$ LC_ALL=ga_IE.iso885915@euro
$ mkdir '€25' && cd '€25'
$ LC_ALL=zh_TW
$ pwd
# ... what should the output be? And what about the output of:
$ /bin/pwd
每个语言环境都包含其他语言环境中不存在的字符。这个问题会影响诸如定位-r和查找-正则表达式也;的论证定位-r是一个正则表达式,因此必须包含对字符类等内容的支持;但您不知道使用什么区域设置来确定路径名称中字符的字符类,或者即使有一个可用的区域设置可用于表示系统上的所有路径。