Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有集合构造的bash通配符扩展_Bash_Perl - Fatal编程技术网

带有集合构造的bash通配符扩展

带有集合构造的bash通配符扩展,bash,perl,Bash,Perl,Bash通配符扩展 我有一个目录,里面有三个文件。我想使用wilcar扩展来匹配program.c和program.o casper@casper-PC ~ $ ls -ltr total 4 drwxr-xr-x+ 1 casper None 0 Apr 12 18:31 perl_lwp -rw-r--r-- 1 casper None 0 Apr 25 00:14 program.o -rw-r--r-- 1 casper None 0 Apr 25 00:14 program.c -

Bash通配符扩展

我有一个目录,里面有三个文件。我想使用wilcar扩展来匹配program.c和program.o

casper@casper-PC ~
$ ls -ltr
total 4
drwxr-xr-x+ 1 casper None 0 Apr 12 18:31 perl_lwp
-rw-r--r--  1 casper None 0 Apr 25 00:14 program.o
-rw-r--r--  1 casper None 0 Apr 25 00:14 program.c
-rw-r--r--  1 casper None 0 Apr 25 00:14 program.log
这是行不通的

casper@casper-PC ~ 
$ ls -ltr | egrep program.[co]
这也不管用

 casper@casper-PC ~ 
$ ls -ltr | egrep program.?
这行不通

casper@casper-PC ~
$ grep -r program.?
这确实有效——但我想使用bash大括号扩展,而不是perl

casper@casper-PC ~
$ ls -ltr | perl -nle 'print /(program.[co])/'
program.o
program.c

然而,我觉得奇怪的是,它同时匹配了这两个元素,因为我认为set构造将匹配o或c,然后在匹配后停止,您可以尝试添加行尾锚点,并将regex放在引号内。请注意,grep使用regex查找字符串而不是glob

ls -ltr | grep 'program\.[co]$'

使用
set-x
查看发生了什么。由于在引号外使用通配符(glob构造),shell在运行
egrep
之前展开文件名

如果要将模式传递给程序,请将它们括在“单引号”中

不要混淆globbing和正则表达式——它们是不同的模式匹配机制。例如:,在正则表达式中,
表示“前面模式的零个或多个”,而在全局搜索中,它只表示一个字符

program.?
在正则表达式中表示“program”,后跟字符串中某个可选的单个字符(
表示除换行符以外的任何字符之一)

program.?
在globbing中表示“program.”,后跟一个字符

egrep
接受正则表达式,而不是glob构造

这也可能是不必要地使用了
ls
egrep
,只需使用
echo

echo program.[co]
   program.c program.o
echo program.?
   program.c program.o
这是因为
echo
是一个内置的shell,shell可以进行全局搜索(通常比调用外部程序(如
ls
)更有效)

现在,您的Perl代码段工作起来有两个原因。第一:您将模式括在单引号中,这不是为
egrep
所做的

第二点:您恰好选择了正则表达式和globbing中唯一相同的模式,[]字符类表示法(尽管这里甚至存在差异)。默认情况下,Perl中的/../notation调用正则表达式匹配(
m
)运算符

您希望Perl匹配在第一次匹配时停止,但是
-nl
选项意味着它对来自管道的标准输入中的每一行执行循环中的
print
语句

顺便说一句,Perl还有内置函数
glob()


您可以尝试glob
ls-ltr*程序。[co]
甚至
echo程序。[co]
无需
grep
ls-l程序。{c,o}
echo *|perl -nle 'print glob("program.[co]")'