我在这里有一个简单的问题:(*
星号通配符)是否仅匹配全局样式的字符(字母和数字)?或者它也会匹配特殊字符?
在 bash 中,*
匹配所有内容,而在 csh 中,*
它仅匹配字母数字字符。
这有什么兼容的规则吗?谁能澄清一下吗?
答案1
*
是匹配任何字符序列的文件名模式。
当用作 glob 时(在文件名扩展/生成中)*
不匹配斜杠字符(好吧,根据当前目录中的文件列表检查该模式)或前导点。
现在的定义是特点随着时间的推移一直在变化。如今,定义或字符取决于语言环境。如今,大多数语言环境对文本使用 UTF-8 编码,这意味着字符是可变长度的字节序列。例如a
0x61 是é
0xc3 0xa9。在 UTF-8 中,并非所有字节序列都构成有效字符。例如 0x61 0xc3 0x61 无效。虽然 0x61 转换为a
,但 0xc3 无法转换为字符。
在大多数 shell 中,*
也将匹配非字符,因此*
将扩展到当前目录中名称不以 开头的所有文件,.
无论文件名中的字节是否构成当前语言环境中的有效字符。一个例外似乎至少是在我的 Debian 系统上发现的 csh-20110502(本身基于 OpenBSD 的 csh)。
$ touch "$(printf '\xc3')" "$(printf '\xc3\xa9')"
$ ls
? é
$ locale charmap
UTF-8
$ bash -c 'echo *' | sed -n l
\303 \303\251$
$ csh -c 'echo *' | sed -n l
\303\251$
\303
(0xc3 字节的表示)在输出中丢失,csh
因为它不是有效字符。
$ LC_ALL=C csh -c 'echo *' | sed -n l
\303 \303\251$
在 C 语言环境中,字符映射到字节(尽管未定义高于 0x7f 的值的字符),因此 0xc3 是一个字符,0xc3 0xa9 是两个字符。
不管怎样,你没有理由csh
在 Debian 上使用它。tcsh
如果您想要类似 shell,请使用csh
,但最好完全避免使用csh
。
答案2
来自 The Open Group 基本规范第 6 期 IEEE Std 1003.1 部分2.13.2 匹配多个字符的模式
星号 ( '*' ) 是一种模式,应匹配任何字符串,包括空字符串。
这意味着*
将不受限制地匹配任何字符。