2011-01-14 91 views
21

我想实现作为命令行中输入如何让bash在变量中扩展通配符?

mv ./images/*.{pdf,eps,jpg,svg} ./images/junk/ 

,从bash脚本里面同样的效果。我有:

MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='{pdf,eps,jpg,svg}' 
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/" 

其中,在运行时,给人的不是意外的错误:

mv: rename ./images/*.{pdf,eps,jpg,svg} to ./images/junk/*.{pdf,eps,jpg,svg}: 
No such file or directory 

什么是引用这一切正确的方式,使mv会怎么做所需的扩张? (是的,有很多匹配./images/该模式的文件。)

回答

22

已删除的答案在正确的轨道上。一个稍微的改变你的尝试:

shopt -s extglob 
MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='@(pdf|eps|jpg|svg)' 
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/" 

括号扩展是变量扩展之前完成,但是变量扩展路径扩展之前完成。因此,当变量在原始文件中展开时,大括号仍然是大括号,但是当变量包含路径名元素时,它们在路径名展开完成时已经被展开。

+3

+1,整洁的技巧,不知道`@()`,我学到了一些新东西。只要在manpage中查看它,对于任何想知道'?()`模式,`*()`模式,`+()`模式,`@()`模式和`!()`模式的人来说。如果启用了“extglob”,则全部可用。 – falstro 2011-01-15 09:43:42

5

你需要EVAL该行,以便它的工作,像这样:

MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='{pdf,eps,jpg,svg}' 
eval "mv \"$MYDIR\"/*.$SUFFIXES \"$OTHERDIR/\"" 

现在,这个有问题,特别是如果你不信任$SUFFIXES,它可能包含注入攻击,但对于这个简单的情况,它应该没问题。

如果您对其他解决方案持开放态度,则可能需要试验findxargs

+1

+1为警告。 `eval`是邪恶的。 – l0b0 2011-01-14 16:02:49