2016-06-01 65 views
4

忽略可以與殼體關聯使用的命令,我想完成從所有目錄和子目錄中排除特定目錄模式的全局模式。殼牌通配不包括目錄模式

比方說,我有這樣的目錄結構:

+-- a 
    +-- a1 
     +-- assets 
        +-- a1-1 
         +-- a1-1.js 
        +-- a1-2 
         +-- a1-2.js 
    +-- a2 
     +-- a2.js 
+-- b 
    +-- b1 
     +-- b1-2 
       +-- b1-2-3 
         +-- assets 
            +-- b1-2-3.js 
    +-- b.js 
+-- c 
    +-- c.js 

我想列出所有的JS沒有在他們的文件路徑assets文件。

我試過到目前爲止:

$ shopt -s globstar extglob 
$ ls ./**/!(assets)/**/*.js 

不僅沒有上述模式實現它的目標,它甚至可以顯示重複的輸出。我知道我可以做這樣的事情:

$ ls ./**/*.js | grep -v "assets" 

或者可以輸送任何其他命令,我只是想純粹殼glob模式。

預期輸出:

a/a2/a2.js 
b/b.js 
c/c.js 

回答

3

Michael的回答是對的。 **匹配太多(貪婪匹配),包括assets

所以,用這種樹:

. 
|-- a 
| |-- a1 
| | +-- assets 
| |  |-- a1-1 
| |  | +-- a1-1.js 
| |  +-- a1-2 
| |   +-- a1-2.js 
| +-- a2 
|  +-- a2.js 
|-- assets 
| +-- xyz.js 
|-- b 
| |-- b1 
| | +-- b1-2 
| |  +-- b1-2-3 
| |   |-- assets 
| |   | +-- b1-2-3.js 
| |   +-- test 
| |    |-- test2 
| |    | +-- test3 
| |    |  +-- test4 
| |    |   +-- test4.js 
| |    +-- test.js 
| +-- b.js 
|-- c 
| +-- c.js 
+-- x.js 

的.js文件是:

$ find . -name '*.js' 
./x.js 
./assets/xyz.js 
./a/a2/a2.js 
./a/a1/assets/a1-2/a1-2.js 
./a/a1/assets/a1-1/a1-1.js 
./c/c.js 
./b/b.js 
./b/b1/b1-2/b1-2-3/test/test2/test3/test4/test4.js 
./b/b1/b1-2/b1-2-3/test/test.js 
./b/b1/b1-2/b1-2-3/assets/b1-2-3.js 

有一個bash變量GLOBIGNORE到底該怎麼做你正在嘗試做的。

那麼,這會工作:

$ GLOBIGNORE='**/assets/**:assets/**:**/assets' 
$ ls -1 **/*.js 
a/a2/a2.js 
b/b1/b1-2/b1-2-3/test/test2/test3/test4/test4.js 
b/b1/b1-2/b1-2-3/test/test.js 
b/b.js 
c/c.js 
x.js 
+0

對不起,但是這個解決方案只顯示一到兩級目錄中的js文件,超出這個範圍的任何js文件都沒有列出。 – ryeballar

+0

對不起,沒有徹底測試...固定... – anishsane

1

的問題是,**比賽太多或你的情況太少。特別地,在!(assets)之前的**將匹配a1/assets/,則!(assets)將匹配a1-1,並且以下**將不匹配,以便總體匹配成功。

考慮該簡化的例子:

touch a/a1/x.js a/a2/y.js a/a3/z.js 
ls ./*/!(a2)/*.js 
ls ./**/!(a2)/**/*.js 

第一ls作品如預期,第二不。

+0

這工作,因爲您示例中的目錄結構組織在同一級別。手頭的問題在於「資產」目錄位於更深層次和不同層次。這根本不能解決問題。 – ryeballar

+0

@ryeballar不,它沒有。但它解釋了爲什麼嘗試失敗。那不是什麼。 –

+0

沒錯,我想這可能是globbing的限制。感謝您的解釋。 – ryeballar

0

這可能是完美的時間讓你開始使用zsh :-)刪除匹配可以簡單地通過~完成:

% setopt extended_glob 
% ls -1 **/*.js~*assets* 
a/a2/a2.js 
b/b.js 
c/c.js