Sté*_*las 13
bash
最初是在 80 年代后期设计的,它是ksh
具有 csh/tcsh 的一些交互功能的部分克隆。
globbing 的起源必须在它构建的那些较早的 shell 中找到。
ksh
本身是 Bourne shell 的扩展。Bourne shell 本身(于 1979 年在 Unix V7 中首次发布)是一个从头开始的干净实现,但它并没有完全脱离 Thompson shell(V1 -> V6 的 shell)并结合了 Mashey shell 的功能。
特别是,命令参数仍然由空格分隔,|
现在是新的管道运算符,但^
仍然作为替代支持(并且还解释了为什么这样做[!a-z]
和不这样做[^a-z]
),$1
仍然是脚本的第一个参数,反斜杠仍然是转义字符. 许多正则表达式运算符 ( ^\|$
) 在 shell 中都有自己的特殊含义。
Thompson shell 依赖于外部实用程序进行通配。当sh
发现不带引号的*
,[
或?
■在命令,它会运行通过命令glob
。
rm *.txt
Run Code Online (Sandbox Code Playgroud)
最终将运行 glob 为:
["glob", "rm", "*.txt"]
Run Code Online (Sandbox Code Playgroud)
并且 glob 最终会运行rm
与该模式匹配的文件列表。
grep a.\*b *.txt
Run Code Online (Sandbox Code Playgroud)
将运行glob
为:
["glob", "grep", "a.\252b", "*.txt"]
Run Code Online (Sandbox Code Playgroud)
在*
上述已经通过设置该字符的第8位,防止引述glob
把它当作一个通配符。glob
然后会在调用之前删除该位grep
。
用正则表达式做等效的事情,那就是:
regexp rm '\.txt$'
Run Code Online (Sandbox Code Playgroud)
或者:
regexp rm '^[^.].*\.txt$'
Run Code Online (Sandbox Code Playgroud)
排除点文件。
需要对运算符进行转义,因为它们兼作 shell 特殊字符,事实上.
,在文件名中常见的是正则表达式运算符,这使得匹配文件名不太合适,并且对于初学者来说很复杂。在大多数情况下,您只需要可以替换一个 ( ) 或任意数量 ( ) 个字符的通配符。?
*
现在,不同的外壳添加了不同的通配符。如今,ksh 和 zsh globs(在某种程度上bash -O extglob
实现了 ksh globs 的一个子集)在功能上等同于 regexp,其语法与文件名和当前的 shell 语法一起使用时不那么麻烦。例如,在zsh
(扩展全局扩展)中,您可以执行以下操作:
echo a#.txt
Run Code Online (Sandbox Code Playgroud)
如果您想(不太可能)匹配a
由.txt
. 比echo (^a*\.txt$)
(这里使用大括号作为一种将正则表达式运算符与 shell 运算符隔离开来的方法更容易,这可能是 shell 处理它的一种方式)。
echo (foo|bar|<1-20>).(#i)mpg
Run Code Online (Sandbox Code Playgroud)
对于基本名称为 foo、bar 或从 1 到 20 的十进制数的 mpg 文件(不区分大小写)...
ksh93
现在还可以在它的 glob 中加入正则表达式(基本的、扩展的、类似 perl 的或“增强的”)(尽管它有很多问题),甚至提供了一个工具来在 glob 和 regexp ( printf %R
, printf %P
)之间进行转换:
echo ~(Ei:.*\.txt)
Run Code Online (Sandbox Code Playgroud)
到比赛(非隐藏),TXT处理文件Ë xtended正则表达式,区分我nsensitively。
正则语言是由Kleene在 1956 年引入的。这篇开创性的论文没有完整的现代正则表达式符号,但它确实引入了“Kleen star”:A*
意思是“任意数量的重复A
”。在接下来的十年中,出现了一些或多或少的标准符号,特别是.
对于任意字符并?
表示前一个字符是可选的。
Bash 的 globbing 表示法源于1971 年在Unix v1中一直引入的glob
命令。当时,globbing 是由一个单独的程序执行的;后来它被移到外壳中。早期命令必须表示“任何一个字符”和“任何字符序列”。我不知道为什么选择这些角色;非常直观,可能受到正则表达式中的启发。glob
?
*
?
*
Globbing 并不像正则表达式那样通用,而且当时正则表达式还不是很普遍,因此没有统一概念的呼吁。从一开始,就存在语法上的不兼容,在文件名模式和正则表达式中?
,.
和 的*
含义不同。
像 bash 这样的现代 shell 扩展了 glob 模式,但它是逐渐演变的,以保持向后兼容性。Ksh88(Korn shell的 1988 版本)引入了 shell 模式的扩展语法,它可能与通常的正则表达式的语法不同,但受到了它的强烈启发:*(PATTERN)
表示任意次数的重复PATTERN
,@(PATTERN1|PATTERN2)
表示“PATTERN1
或PATTERN2
”,等等。
如果您shopt -s extglob
先发布,现代版本的 bash(自 2.02 起)支持 ksh88 的扩展模式。
归档时间: |
|
查看次数: |
1365 次 |
最近记录: |