2011-01-14 20 views
21

私はbashスクリプト内から、コマンドラインで変数でbash拡張ワイルドカードを作成する方法は?

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

を入力するのと同じ効果を達成しようとしています。私が持っている:

実行し、
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/" 

可変拡張前に中括弧拡張が行われますが、パス名展開前に可変拡張が行われます。したがって、変数が元の場所で展開されている場合でも中括弧は中カッコですが、変数にpathname要素が含まれている場合は、パス名展開が完了したときに既に展開されています。

+3

+1、きちんとしたトリック、 '@()'について知らなかった、新しいことを学んだ。 (?)パターン、 '*()'パターン、 '+()'パターン、 '@()'パターン、 '!()'パターンがあるのを知っている方はマンページで調べてみてください。 'extglob'が有効な場合はすべて利用可能です。 – falstro

+0

素晴らしい、ありがとう!シェルスクリプトの引用と展開は常に問題を引き起こしますが、これは大いに役立ちます。 –

+1

@RossDuncan、私はhttp://mywiki.wooledge.org/BashParserを、シェルの実行モデルに関係するフェーズや、どのような順番で起きているかについての良い参照をする場所として提案したいと思います。 –

5

あなたがそうのように、それが機能するためには、その行をevalに必要があります:

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

さて、これは問題があります特に、あなたが$SUFFIXESを信用していないなら、それは注射攻撃を含んでいるかもしれませんが、この単純なケースのためには大丈夫でしょう。

他のソリューションをご利用の場合は、findxargsを試してみるとよいでしょう。

+1

+1の警告。 'eval'は悪です。 – l0b0

関連する問題