bash
最初是在80年代后期设计的,是对ksh
csh / tcsh的某些交互功能的部分克隆。
浮球的起源必须在它所建立的早期外壳中找到。
ksh
本身是Bourne外壳的延伸。Bourne shell本身(于1979年在Unix V7中首次发布)从头开始是一个干净的实现,但是它并没有完全脱离Thompson shell(V1-> V6的外壳),并结合了Mashey shell的功能。
特别是,命令参数仍然由空格分隔,|
现在是新的管道运算符,但^
仍然受支持(并且也解释了为什么这样做[!a-z]
而不是[^a-z]
),$1
仍然是脚本的第一个参数,反斜杠仍然是转义字符。因此,许多regexp运算符(^\|$
)在shell中都有自己的特殊含义。
Thompson shell依赖于外部实用程序来进行通配。当sh
发现不带引号的*
,[
或?
■在命令,它会运行通过命令glob
。
rm *.txt
最终将glob运行为:
["glob", "rm", "*.txt"]
而glob最终将运行rm
与该模式匹配的文件列表。
grep a.\*b *.txt
将运行glob
为:
["glob", "grep", "a.\252b", "*.txt"]
在*
上述已经通过设置该字符的第8位,防止引述glob
把它当作一个通配符。glob
然后会在调用之前删除该位grep
。
要对正则表达式进行等效处理,那就是:
regexp rm '\.txt$'
要么:
regexp rm '^[^.].*\.txt$'
排除点文件。
需要避免将运算符用作shell特殊字符,因为.
文件名中常见的regexp运算符使它不适合匹配文件名,并且对于初学者来说很复杂。在大多数情况下,您只需要通配符即可替换一个(?
)或任意数量(*
)的字符。
现在,不同的外壳添加了不同的全局操作符。如今,ksh和zsh glob(在某种程度上bash -O extglob
实现了ksh glob的子集)在功能上等效于正则表达式,其语法在使用文件名和当前shell语法时不再那么麻烦。例如,在zsh
(具有extensionglob扩展名)中,您可以执行以下操作:
echo a#.txt
如果您希望(不太可能)匹配由a
后跟组成的文件名.txt
。比echo (^a*\.txt$)
(在这里使用花括号作为将regex运算符与shell运算符隔离的方法更容易),这可能是shell处理它的一种方式。
echo (foo|bar|<1-20>).(#i)mpg
对于基本名称为foo,bar或1到20的十进制数字的mpg文件(不区分大小写)...
ksh93
现在还可以将regexp(基本的,扩展的,类似perl的或“增强的”)合并到其glob中(尽管它有很多bug),甚至还提供了在glob和regexp(printf %R
,printf %P
)之间转换的工具:
echo ~(Ei:.*\.txt)
到比赛(非隐藏),TXT处理文件Ë xtended正则表达式,区分我 nsensitively。
rm -- ^[^.].*\.txt$
代替rm -- *.txt
吗?