ループを使用してBashコードを動的に生成し、生成されたとおりに実行する方法

ループを使用してBashコードを動的に生成し、生成されたとおりに実行する方法

以下のように、Bashスクリプトに行リストがあります。

if [ ! -z "$clone01" ]; then git clone "$clone01"; fi
if [ ! -z "$clone02" ]; then git clone "$clone02"; fi
if [ ! -z "$clone03" ]; then git clone "$clone03"; fi
#      $clone01 .... through to ...  $clone60
if [ ! -z "$clone60" ]; then git clone "$clone60"; fi

数値が 10 より小さい場合は、変数の末尾に先行ゼロが重要です。

様々な代替やループなどを試しました。このコードは非常に反復的で、60行で構成されています。

このコードを動的に生成して実行するスクリプトの一部にするにはどうすればよいですか?この問題を解決するための最良の方法は何ですか?

答え1

まあ、そうしないでください。見苦しいです。 URLを配列に入れて繰り返します。

urls=( http://this.git http://that.git )
for url in "${urls[@]}" ; do
    git clone "$url"
done

または、1行に1つずつファイルに入れ、ループからその行を読み取ります。ここでは、あなたのように空白行を防ぐのが便利です。#asコメントで始まる行を無視することもできます。

while read -r url ; do
    if [ -z "$url" ] || [ "${url:0:1}" = "#" ]; then continue; fi
    git clone "$url"
done < file.with.urls

行カウンタも必要に応じて簡単に追加できます。算術拡張

答え2

これを行うために使用しないでくださいeval。より良いツールは可変間接:

for i in clone{01..60}; do 
   [[ ${!i} ]] && git clone "${!i}"
done

[[ $var ]]と同じ効果があります[ ! -z "$var" ]。 60個の変数に60個の値を格納するのは最善の方法ではなく、そのために配列を使用する必要があるかもしれません。

答え3

ifをこのようなforループでパッケージ化してみましたか?

for i in clone{01..60}; do echo $i; done

これにより、次のような出力が生成されます。

clone01
clone02
clone03
... clipped for length ...
clone60

だから、このようなものがトリックを実行しているようです。

for i in clone{01..60}; do if [ ! -z $i ]; then git clone $i; fi; done

これに役立つリソース:

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html

http://tldp.org/LDP/abs/html/varsubn.html

関連情報