タイピングと同じ効果を得ようとしています
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/
のパターンに一致するファイルがたくさんあります。)
削除された回答は正しい軌道に乗っていました。あなたの試みを少し変更します:
shopt -s extglob
MYDIR="./images"
OTHERDIR="./images/junk"
SUFFIXES='@(pdf|eps|jpg|svg)'
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/"
ブレース展開は変数展開の前に行われますが、変数展開はパス名展開の前に行われます。したがって、元の変数が展開された場合でも中括弧は中括弧になりますが、変数にパス名要素が含まれている場合は、パス名の展開が行われたときに既に展開されています。
次のように機能するためには、その行を評価する必要があります。
MYDIR="./images"
OTHERDIR="./images/junk"
SUFFIXES='{pdf,eps,jpg,svg}'
eval "mv \"$MYDIR\"/*.$SUFFIXES \"$OTHERDIR/\""
さて、これは特に信頼できない場合、特に問題があります$SUFFIXES
、インジェクション攻撃が含まれている可能性がありますが、この単純なケースでは問題ありません。
他のソリューションを利用できる場合は、find
とxargs
を試してみてください。
あなたは関数を書くことができます:
function expand { for arg in "$@"; do [[ -f $arg ]] && echo $arg; done }
次に、拡張したいものでそれを呼び出します:
expand "$MYDIR/"*.$SUFFIXES
必要に応じて、スクリプトをexpand.shにすることもできます。