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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4691956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:05:11  来源:igfitidea点击:

how to make bash expand wildcards in variables?

bashscriptingexpansion

提问by Ross Duncan

I am trying achieve the same effect as typing

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

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

at the command line, from inside a bash script. I have:

在命令行,从 bash 脚本内部。我有:

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

which, when run, gives the not unexpected error:

运行时,会出现意外错误:

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

What is the correct way to quote all this so that mvwill actually do the desired expansion? (Yes, there are plenty of files that match the pattern in ./images/.)

引用所有这些以便mv实际进行所需的扩展的正确方法是什么?(是的,有很多文件与./images/.中的模式匹配。)

回答by Paused until further notice.

A deleted answer was on the right track. A slight modification to your attempt:

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

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

Brace expansion is done before variable expansion, but variable expansion is done before pathname expansion. So the braces are still braces when the variable is expanded in your original, but when the variable instead contains pathname elements, they have already been expanded when the pathname expansion gets done.

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

回答by falstro

You'll need to eval that line in order for it to work, like so:

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

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

Now, this has problems, in particular, if you don't trust $SUFFIXES, it might contain an injection attack, but for this simple case it should be alright.

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

If you are open to other solutions, you might want to experiment with findand xargs.

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

回答by Dagang

You can write a function:

你可以写一个函数:

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

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

then call it with what you want to expand:

然后用你想要扩展的东西调用它:

expand "$MYDIR/"*.$SUFFIXES

expand "$MYDIR/"*.$SUFFIXES

You can also make it a script expand.sh if you like.

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