Bash のネストされた for ループ

Abdul Mateen 2023年6月20日
  1. Bash の for ループのバリエーション
  2. Bash のネストされた for ループ
Bash のネストされた for ループ

このチュートリアルでは、bash のネストされたループについて説明します。 最初に、bash で利用可能なさまざまな for ループ形式について簡単に説明します。 次に、ネストされた for ループについて例を挙げて説明します。

Bash の for ループのバリエーション

まず、bash の for ループの構文を見てみましょう。

for var in something
do
    command
done

この構文では、変数名はユーザーが選択します。 something には複数のオプションがありますが、これについては後ほど説明します。

for 本体内に任意の数のコマンドを記述できます。 複数の for ループのバリエーションが bash で利用可能です。 以下にいくつかを簡単に示します。

数値範囲のfor

次の例に示すように、for ループで数値のリストを指定し、それらの数値を 1つずつ反復できます。

for i in 1 3 8
do
    echo $i
done

ループは、指定された値のリスト (つまり、1 3 8) を繰り返します。 この特定の例では、出力は次のようになります。

1
3
8

値リストのfor

値のリストを定義し、次のようにリストを反復処理できます。

x=(1 3 8)
for i in ${x[@]}
do
    echo $i
done

このコードの結果は、前の例の出力と同じになります。 for ループ ステートメントでは、{x[@]} は次を表します: リスト x のすべての要素に対して。

シーケンスの範囲内のfor

値の範囲は、開始番号、2つのドット (..)、および終了番号で指定できます。 同様に、もう 1 組のドットの後にステップを配置できます。

たとえば、次の 2つのループ形式の例を見てみましょう。

for i in {1..3}
do
    echo $i
done
echo "----------------------"
for i in {1..3..2}
do
    echo $i
done

このコードの出力は次のようになります。

1
2
3
----------------------
1
3

単語を含む文字列内のfor

次のように、スペースで区切られた文字列内の単語のリストを定義し、文字列内の単語を反復処理できます。

names="Asim Babar Munir Ali"
for name in $names
do
    echo $name
done

このコードの出力には、次のように別々の行に名前が付けられます。

Asim
Babar
Munir
Ali

C スタイルの for

C言語のforと同様に、forループで式を与えることができます。 例を参照してください。

for ((i=1;i<=5;i++))
do
    echo $i
done

次の出力が生成されます。

1
2
3
4
5

for ループでの continue ステートメントの使用

for ループの本体にいくつかの条件を配置し、その後に continue ステートメントを続けて、ループの次の本体をスキップすることができます。 例を参照してください。

for ((i=1;i<=5;i++))
do
    if [ $i == 3 ]
    then
        continue
    fi
    echo $i
done

if 条件により、ループは値 3echo コマンドをスキップします。 したがって、出力は 1 2 4 5 になります。

コマンド ライン引数のループ

コマンドライン引数を bash スクリプトに与えて、スペースで区切られた引数に対して for ループを実行できます。 例を参照してください。

for i in $@
do
    echo "Script arg is $i"
done

最初の行の $@ 記号は、スペースで区切られた引数のリストを表します。 この例の出力を参照してください。

bash myscript.sh 13 28
Script arg is 13
Script arg is 28

コマンド出力のループ

コマンドの出力に対して for ループを実行できます。 例を参照してください。

for f in $(ls)
do
  echo "**** $f *****"
done

このスクリプトは ls コマンドの出力を取得し、値を反復処理します。 出力例を参照してください。

**** first.c *****
**** second.c *****
**** third.c *****

変数シーケンスのループ

実行時に変数に基づいて入力を実行することもできます。 これには、seq 1 1 $n を使用できます。ここで、n は変数にすることができます。 例を参照してください。

n=4
for i in $(seq 1 1 $n)
do
    echo -n $i
    echo " "
done

ここでは、値 4 を変数に代入していますが、これは単語数などの数にすることができます。出力例を参照してください。

1
2
3
4

Bash のネストされた for ループ

bash にはさまざまなネストされた for ループがあります。 要件に応じて、ネストされた for ループのいくつかのバリエーションを作成できます (つまり、利用可能な for ループの定式化を組み合わせることによって)。

ここでは、出力とともに複数の例を示します。

  • 最初の 5つの正の整数の最初の 10 の倍数を出力します。
    for number in {1..5}
    do
    	for n in {1..10}
    	do
    		echo -n $((number*$n))
    		echo -n " "
    	done
    	echo ""
    done
    

    このコードの出力は次のとおりです。

    1 2 3 4 5 6 7 8 9 10
    2 4 6 8 10 12 14 16 18 20
    3 6 9 12 15 18 21 24 27 30
    4 8 12 16 20 24 28 32 36 40
    5 10 15 20 25 30 35 40 45 50
    
  • 整数のリストの最初の 10 個の倍数を出力します。
    for number in 2 5 9
    do
    	for n in {1..10}
    	do
    		echo -n $((number*$n))
    		echo -n " "
    	done
    	echo ""
    done
    

    このコードの出力は次のとおりです。

    2 4 6 8 10 12 14 16 18 20
    5 10 15 20 25 30 35 40 45 50
    9 18 27 36 45 54 63 72 81 90
    
  • 三角形のパターンで数字を印刷します。
    for number in {1..5}
    do
    	for n in $(seq 1 1 $number)
    	do
    		echo -n $n
    	done
    	echo ""
    done
    

    このコードの出力は次のとおりです。

    1
    12
    123
    1234
    12345
    

    コマンド ライン引数から数行を取得して、可変サイズのパターンを出力する場合があります。 コードを参照してください:

    for number in $(seq 1 1 $@)
    do
    	for n in $(seq 1 1 $number)
    	do
    		echo -n $n
    	done
    	echo ""
    done
    

    コマンド bash pattern2.sh 6 の出力は次のとおりです。

    1
    12
    123
    1234
    12345
    123456
    

    patter2.sh はこのスクリプトの名前で、6 はコマンド ライン引数です。

  • アスタリスク (*) またはその他の文字で三角形のパターンを印刷します。
    for number in $(seq 1 1 $@)
    do
    	for n in $(seq 1 1 $number)
    	do
    		echo -n "*"
    	done
    	echo ""
    done
    

    引数 4 を持つコードの出力は次のとおりです。

    *
    **
    ***
    ****
    
  • メッセージを複数回出力します (強調するため)。
    messages="Sea_is_rough Don't_go_too_far_in_the_sea Remain_in_the_group Don't_take_kids_inside"
    for i in 1 2 3 4 5
    do
    	for message in $messages
    	do
    		echo $message
    	done
    	echo "----------------------------------"
    done
    

    これの出力は次のとおりです。

    Sea_is_rough
    Don't_go_too_far_in_the_sea
    Remain_in_the_group
    Don't_take_kids_inside
    ----------------------------------
    Sea_is_rough
    Don't_go_too_far_in_the_sea
    Remain_in_the_group
    Don't_take_kids_inside
    ----------------------------------
    Sea_is_rough
    Don't_go_too_far_in_the_sea
    Remain_in_the_group
    Don't_take_kids_inside
    ----------------------------------
    Sea_is_rough
    Don't_go_too_far_in_the_sea
    Remain_in_the_group
    Don't_take_kids_inside
    ----------------------------------
    Sea_is_rough
    Don't_go_too_far_in_the_sea
    Remain_in_the_group
    Don't_take_kids_inside
    ----------------------------------
    
  • 1 から数えて 1 行に出力します。 コマンドライン引数のリストまでカウントを出力する必要があります。
    for number in $@
    do
    	for i in $(seq 1 1 $number)
    	do
    		echo -n "$i "
    	done
    	echo ""
    done
    

    Bash count.sh 4 5 8 のこのコードの出力は次のとおりです。

    1 2 3 4
    1 2 3 4 5
    1 2 3 4 5 6 7 8
    
  • 10 から 20 の倍数を表示しますが、この数列で素数の倍数を表示しないでください。
    for number in $(seq 10 1 20)
    do
    	if [[ $number == 11 || $number == 13 || $number == 17 || $number == 19 ]]
    	then
    		continue
    	fi
    	for n in {1..10}
    	do
    		echo -n $((number*$n))
    		echo -n " "
    	done
    	echo ""
    done
    

    このコードの出力は次のとおりです。

    10 20 30 40 50 60 70 80 90 100
    12 24 36 48 60 72 84 96 108 120
    14 28 42 56 70 84 98 112 126 140
    15 30 45 60 75 90 105 120 135 150
    16 32 48 64 80 96 112 128 144 160
    18 36 54 72 90 108 126 144 162 180
    20 40 60 80 100 120 140 160 180 200
    

結論として、bash にはネストされたさまざまな for ループがあります。 したがって、要件に応じて利用可能な for ループのバリエーションの組み合わせを使用して、タスクを完了することができます。