web-dev-qa-db-ja.com

シーケンスのシェルブレース展開で$ variableを使用するにはどうすればよいですか?

$var inを使用して、bashで範囲付きのシェルブレース展開を使用したいと思います。単に{$var1..$var2}を置くだけでは機能しないので、「横向き」にしました...

次のように動作しますが、少し厄介です。

# remove the split files
echo rm foo.{$ext0..$extN} rm-segments > rm-segments
source rm-segments

より「通常の」方法はありますか?

37
Peter.O

あなたは試してみたいかもしれません:

eval rm foo.{$ext0..$extN}

これが最良の答えかどうかはわかりませんが、確かに1つです。

32
asoundmove

他の回答ではevalseqの使用について説明していますが、bashでは、算術コンテキストで従来のCスタイルのforループを使用できます。変数ext0およびextN((..))内で展開され、定義された範囲でループが実行されます。

for (( idx = ext0; idx <= extN; idx++ )); do
    [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue ; }
    rm "$foo.$idx"
done

最適な方法を探しており、複数のrmコマンドを回避する場合は、一時的なプレースホルダーを使用してファイル名の結果を保存し、rmをワンショットで呼び出すことができます。

 results=()
 for (( idx = ext0; idx <= extN; idx++ )); do
     [[ -f "$foo.$idx" ]] || { printf "file %s does not exist" "$foo.$idx" >&2 ; continue ; }
     results+=( "$foo.$idx" )
 done

拡張された配列でrmコマンドを呼び出します

 rm -- "${results[@]}"
2
Inian
    function f_over_range {
        for i in $(eval echo {$1..$2}); do
            f $i
        done
    }

    function f {
        echo $1
    }

    f_over_range 0 5
    f_over_range 00 05

ノート:

  • Evalを使用すると、コマンドインジェクションのセキュリティリスクが明らかになります
  • Linuxは「00\n01\n02..etc」を出力しますが、OSXは「1\n2\n ... etc」を出力します
  • シーケンスまたはCスタイルのforループを使用すると、ブレース展開の先行ゼロの処理と一致しません
0
Ready