2015-04-25 125 views
0

bash通配符擴展。使用set構造的bash通配符擴展

我有一個包含三個文件的direcotry。我想用wilcar擴展來匹配program.c和program.o

[email protected] ~ 
$ 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 

這是行不通的。

[email protected] ~ 
$ ls -ltr | egrep program.[co] 

這項工作也沒有。

[email protected] ~ 
$ ls -ltr | egrep program.? 

這不起作用

[email protected] ~ 
$ grep -r program.? 

這樣做的工作 - 但我想使用bash括號展開,不使用Perl。

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

但是我覺得奇怪的是,它匹配他們兩個,因爲我認爲這組結構將匹配O或C,然後停止,一旦匹配

+0

無需'grep':'ls -l命令程序{C,O}' – ThisSuitIsBlackNot

回答

0

你可以嘗試添加行錨端也把正則表達式放在引號內。請注意,grep使用正則表達式來查找不是glob的字符串。

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

,你可以嘗試'glob的LS -ltr *程序[合作]' –

+0

甚至'回聲程序[合作。 ]' – cdarke

2

使用set -x來查看發生了什麼。由於您正在使用通配符(glob結構)外部引號,因此shell擴展文件名之前egrep得到運行。

如果您想將模式傳遞給程序,將它們放在'單引號'內。

不要混淆globbing與正則表達式 - 他們是不同的模式匹配製度。例如:,在正則表達式中,?意味着「零個或多個前面的模式」,而在globbing中意味着正好是的一個字符。

在正則表達式program.?是指「程序」接着任選的單個字符(.指除換行符任何字符中的一個)某處的字符串英寸

program.?中的globbing表示「程序」。隨後是一個單個字符。

egrep需要正則表達式,而不是glob結構。

這也可能兩者lsegrep的不必要的使用,只要使用echo

echo program.[co] 
    program.c program.o 
echo program.? 
    program.c program.o 

這工作,因爲echo是一個shell內置和外殼沒有通配符(通常比更有效調用外部程序如ls)。

現在你的Perl代碼片段有兩個原因。其一:你把這個模式放在單引號內,你沒有爲egrep做過。

二:你剛好挑只有模式是在正則表達式相同,通配符 - 在[] 字符類符號(儘管有此甚至差異)。 Perl中的/.../表示法默認調用正則表達式匹配(m)運算符。

您預期Perl匹配會在第一次匹配時停止,但-nl選項意味着它會爲來自管道的標準輸入中的每一行循環執行print語句。

順便說一句,Perl也有內置功能​​3210。

echo *|perl -nle 'print glob("program.[co]")'