2016-06-01 66 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