35

我正在尝试达到与打字相同的效果

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/。)

4

3 回答 3

36

已删除的答案在正确的轨道上。对您的尝试稍作修改:

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

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

于 2011-01-14T17:18:14.953 回答
9

您需要评估该行才能使其正常工作,如下所示:

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

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

如果您对其他解决方案持开放态度,您可能想尝试使用findxargs

于 2011-01-14T14:23:40.847 回答
4

你可以写一个函数:

function expand { for arg in "$@"; do [[ -f $arg ]] && echo $arg; done }

然后用您要扩展的内容调用它:

expand "$MYDIR/"*.$SUFFIXES

如果您愿意,也可以将其设为脚本 expand.sh。

于 2018-10-05T02:13:33.240 回答