Pet*_*r.O 7 bash wildcards locale variable-substitution
我认为 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
Run Code Online (Sandbox Code Playgroud)
输出:
0000000: 2009 .
0000000: 2061 2062 a b
0000000: 20e0 20a4 20b3 . . .
Run Code Online (Sandbox Code Playgroud)
您的问题的简短答案是 *(pattern-list) 将匹配给定模式的零次或多次出现。每个输入字节之间有零个 Unicode 字符 0001 实例。因此,替换操作将这零个实例中的每一个替换为一个空格。
\n\n也许你想这样做:
\n\n$ for str in $\'\\t\' "ab" \xe0\xa4\xb3 ; do \n printf -- \'%s\' "${str//+($\'\\x01\')/ }" |xxd\n done)\n0000000: 09 .\n0000000: 6162 ab\n0000000: e0a4 b3 ...\nRun Code Online (Sandbox Code Playgroud)\n\n但更长的答案是,无论如何,路径名都不是文本。至少,就(类 Unix)操作系统而言,它们还不够。它们是字节序列。问题是这样的事情做起来很简单:
\n\n$ LC_ALL=latin1\n$ mkdir \'\xc3\xa1\xc3\xb1\' && cd \'\xc3\xa1\xc3\xb1\'\n$ LC_ALL=ga_IE.iso885915@euro\n$ mkdir \'\xe2\x82\xac25\' && cd \'\xe2\x82\xac25\'\n$ LC_ALL=zh_TW\n$ pwd\n# ... what should the output be? And what about the output of:\n$ /bin/pwd\nRun Code Online (Sandbox Code Playgroud)\n\n每个语言环境都包含其他语言环境中不存在的字符。这个问题也会影响像locate -r和find -regex这样的东西;locate -r的参数是一个正则表达式,因此必须包含对字符类等内容的支持;但您不知道使用什么区域设置来确定路径名中字符的字符类,或者即使有一个可用的区域设置可用于表示系统上的所有路径。
\n