如何使bash扩展变量中的通配符?

时间:2011-01-14 14:16:54

标签: bash scripting expansion

我正在尝试达到与输入

相同的效果
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/中的模式匹配。)

3 个答案:

答案 0 :(得分:27)

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

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

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

答案 1 :(得分:8)

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

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

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

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

答案 2 :(得分:0)

您可以编写一个函数:

loopback

然后使用您要扩展的名称进行调用:

INSERT INTO res_booking_status (AirlineCode, flightnumber, departuredate, totalbooking,:#${header[Subclass]}) Values (:#${header[AirlineCode]}, :#${header[FlightNumber]}, :#$ { header[departuredate] }, 1, 1 );

如果愿意,还可以使其成为脚本expand.sh。