Linux Bash スクリプトにおける for ループの 9 つの例

  • Bash の for ループは、数値、単語、配列、コマンドライン変数、または他のコマンドの出力を処理できる多用途ツールです。
  • 単純な for ループは、数値リストまたは単語リストで使用でき、リストの各値に対してコードのセクションを繰り返すことができます。
  • for ループは、数値範囲、ファイル名、コマンドライン パラメータ、単語配列、および連想配列でも使用できるため、スクリプティング タスクの柔軟性が高まります。

多用途な Bashforループは、一定回数ループする以上のことができます。その多くのバリエーションについて説明しますので、独自の Linux スクリプトでうまく使用することができます。

for ループ

すべてのスクリプティング言語とプログラミング言語には、ループを処理する方法があります。ループとは、繰り返し実行するコードのセクションのことです。同じ一連の命令をスクリプトに何度も入力する代わりに、ループはコードの 1 つのセクションを繰り返し実行します。

Bashforループは非常に柔軟です。数値、単語、配列、コマンドライン変数、または他のコマンドの出力を処理できます。これらはループのヘッダーで使用されます。ヘッダーは、ループが処理する内容 (数値または文字列など) と、ループを停止する終了条件を指示します。

ループの本体には、繰り返し実行するコードが含まれています。ループに実行させたい内容が保持されます。ループの本体には、有効なスクリプト コマンドを何でも含めることができます。

ループ カウンターまたはイテレータと呼ばれる変数は、値の範囲またはデータ項目のリストをステップ実行するために使用されます。ループごとに、イテレータは次の数値、文字列、またはループがイテレートしているデータ型を取得します。これにより、ループは順番に各データ項目の値を処理したり、場合によってはデータ項目自体を操作したりすることができます。

単純な for ループ

最初の for ループを作成する場合は、これらの単純な例から始めます。

数値リストを使用した for ループ

コマンドラインでforループを実行できます。このコマンドは、単純なforループを作成して実行します。イテレータはiという変数です。iを順番に数値リストの各値に割り当てます。ループの本体はその値を端末ウィンドウに出力します。このループを終了する条件は、iが数値リスト全体をイテレートしたときです。

for i in 1 2 3 4 5; do echo $i; done

ここで注意すべき重要な点は、ループが回るたびに変数iが 1 ずつ増加することですが、これは数値リストが毎回 1 ずつ増加するためです。

この数値リストは 3 から始まり、2 ずつ増えていき、44 で不規則に飛躍します。

for i in 3 5 7 9 11 44; do echo $i; done

forループには影響しません。リストの一方の端から始めて、リストのすべての値を使用するまで、順番に各値を使用します。

数値は昇順である必要もありません。どのような順序でもかまいません。

for i in 3 43 44 11 9; do echo $i; done

単語リストを使用した for ループ

同じことを単語でも簡単に実行できます。スクリプトのテキストをエディタにコピーして、「word-list.sh」という名前で保存します。

<code>#!/bin/bash
for word in This is a sequence of words
do
echo $word
done</code>

chmodを使用してスクリプトを実行可能にする必要があります。また、この記事からコピーした他のスクリプトも実行可能にする必要があります。chmodコマンドを使用するたびに、スクリプトの名前を置き換えるだけです。

chmod +x word-list.sh

スクリプトを実行してみましょう。

./word-list.sh

数値の場合と同様に、イテレータ (この例では変数word) は、リストの最後に到達するまでデータ項目のリストを処理します。ループの本体は、word変数の値にアクセスするため、リストの各単語が処理されます。

数値範囲を使用した for ループ

forループを 100 回実行したい場合、ループ ヘッダーに 100 個の数字のシーケンスを入力する必要があるため、かなり面倒な作業になります。数値範囲を使用すると、最初と最後の数値のみを指定できます。

このスクリプトは「number-range.sh」です。

<code>#!/bin/bash
for i in {1..10}
do
echo "Loop spin:" $i
done</code>

数値範囲は中括弧「{}」で定義され、2 つのピリオド「..」で範囲の開始と終了の数値を区切ります。範囲の定義に空白を含めないように注意してください。

実行方法は次のとおりです。

./number-range.sh

イテレータが範囲内の数値を移動するために使用するステップ サイズを定義する別の数値を含めることができます。このスクリプト「number-range2.sh」は、0 から 32 までの範囲と、ステップ サイズ 4 を使用します。

<code>#!/bin/bash
for i in {0..32..4}
do
echo "Loop spin:" $i
done</code>

イテレータは 4 ずつジャンプして数値範囲を移動します。

./number-range2.sh

ファイル名を使用した for ループ

単語のリストを処理できるため、スクリプトでファイル名を使用することができます。このスクリプトは「filenames.sh」と呼ばれます。

<code>#!/bin/bash
for file in word-list.sh number-range.sh number-range2.sh filenames.sh
do
ls -lh "$file"
done</code>

lsができることしかできないスクリプトがあってもほとんど意味がありませんが、ループの本体内でファイル名にアクセスする方法を示しています。

./filenames.sh

数値範囲を使用する場合と同様に、ループ ヘッダーでファイル パターンを使用して、処理するファイルを指定できます。これにより、入力が大幅に削減され、事前にファイル名を知る必要がなくなります。

このスクリプトは「filenames2.sh」と呼ばれます。ファイル名のリストをファイル名パターン「*.sh」に置き換えて、スクリプトで現在のディレクトリにあるすべてのスクリプト ファイルをレポートします。

<code>#!/bin/bash
for file in *.sh
do
ls -lh "$file"
done</code>

出力がこちらです。

./filenames2.sh

コマンドライン パラメータを使用した for ループ

コマンドラインでファイル名パターンを渡すことで、さらに柔軟性を高めることができます。$*変数は、スクリプトに渡されたすべてのコマンドライン パラメータを表します。

これは「filenames3.sh」です。

<code>#!/bin/bash
for file in $*
do
ls -lh "$file"
done</code>

「n」で始まり、SH 拡張子を持つファイル名を指定します。

./filenames3.sh n*.sh

一度に複数のパターンを渡すこともできます。

./filenames3.sh n*.sh .bashrc

イテレータ変数fileは、各コマンドライン パラメータの値になります。ファイル名パターンは展開され、すべてのファイル名はループ本体で処理されます。

C ライクな for ループ

Bash は、C プログラミング言語にあるような、古典的な 3 項 for ループをサポートしています。ループ ヘッダーに 3 つの項があるため、3 項 for ループと呼ばれます。

  • ループ イテレータの初期値。
  • ループを継続するか終了するかをテストします。
  • イテレータの増分 (または減分)。

このスクリプトは「c-like.sh」です。

イテレータIはループの開始時に 1 に設定され、ステートメント「i<=10」が true である限りループは実行されます。iが 11 に達するとすぐに、forループは停止します。イテレータは、ループの回転ごとに 1 ずつ増加します。

<code>#!/bin/bashfor (( i=1; i<=10; i++ ))
do
echo "Loop number:" $i
done</code>

このスクリプトを実行してみましょう。

./c-like.sh

C ライクなforループを使用すると、要件が少し変わったforループを簡単に作成できます。このループは 15 から始まり、3 ずつカウントダウンします。これは「c-like2.sh」です。

<code>#!/bin/bash
for (( i=15; i>0; i-=3 ))
do
echo "Loop number:" $i
done</code>

実行すると、3 ずつ後退します。

./c-like2.sh

無限 for ループ

この形式のforループを使用して、無限ループを作成することもできます。必要なのは、ループ ヘッダーからすべての要素を削除することだけです。これは「infinite.sh」です。

<code>#!/bin/bash
for (( ; ; ))
do
echo "Press Ctrl+C to stop..."
sleep 1
done</code>

ループを停止するには Ctrl+C を押す必要があります。

./infinite.sh

単語配列を使用した for ループ

単語の配列を簡単に反復処理できます。ループ ヘッダーで配列の名前を指定する必要があります。イテレータは配列のすべてのエントリを処理します。これは「word-array.sh」です。

<code>#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributions
do
echo $distro
done</code>

すべてのディストリビューションがリストされます。

./word-array.sh

continue コマンド

ループが特定のエントリをステップオーバーするようにする場合は、イテレータがそのエントリと一致するかどうかをテストし、continueコマンドを使用します。continueコマンドは、現在のループのスピンを放棄します。イテレータをインクリメントし、ループの次のスピンを開始します (スキップするエントリがリストの最後の項目ではないと想定)。

これは「word-array2.sh」です。「Arch」配列エントリをステップオーバーしますが、他のすべての配列メンバーを処理します。

<code>#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributionsdo
if [[ "$distro" == "Arch" ]] ;
then
continue
fi
echo $distro
done</code>

ターミナル ウィンドウに「Arch」は表示されません。

./word-array2.sh

break コマンド

breakコマンドはループを破棄し、それ以上の処理を防止します。

これは「word-array3.sh」です。continuebreakに置き換えた以外は、前のスクリプトと同じです。

<code>#!/bin/bash
distributions=("Ubuntu Fedora Manjaro Arch EndeavourOS Garuda")
for distro in $distributions
do
if [[ "$distro" == "Arch" ]] ;
then
break
fi
echo $distro
done</code>

イテレータに「Arch」が含まれている場合、for ループはそれ以上の処理を放棄します。

./word-array3.sh

連想配列を使用した for ループ

Bash 4 以降では、連想配列を使用すると、キーまたは値で検索できるキーと値のペアのリストを作成できます。キーと値の間に双方向の関係があるため、データ ディクショナリとも呼ばれます。

forループを使用して連想配列を反復処理できます。このスクリプトは「associative.sh」です。4 つのエントリがある連想配列を定義します。それぞれが「dog」、「cat」、「robin」、および「human」に対応します。これらがキーです。値は、それぞれが持つ脚の数 (デフォルト) です。

<code>#!/bin/bash

declare -A animals=( [dog]=Four-legged [cat]=Four-legged [robin]=Two-legged [human]=Two-legged )

for legs in ${!animals[@]}
do
if [ ${animals[$legs]} == "Two-legged" ]; then
echo ${legs}
fi
done

イテレータはlegsと呼ばれます。ループ ヘッダーには「!」感嘆符が含まれていることに注意してください。これは論理 NOT 演算子としては機能せず、連想配列構文の一部です。配列を検索する必要があります。

ループの本体は文字列比較テストを実行します。配列メンバーの値が「Two-legged」の場合、キー値をターミナル ウィンドウに出力します。実行すると、スクリプトは二足歩行の生き物を印刷します。

./associative.sh

コマンドの出力の反復処理

ファイル名など、何かのリストを生成するコマンドまたはコマンド シーケンスがある場合は、forループを使用して反復処理できます。予期しないファイル名の展開に注意する必要がありますが、単純な場合は問題ありません。

このスクリプトは「command.sh」です。lswcを使用して、スクリプト ファイル名のソートされたリストと、それらの行、単語、およびバイト数を提供します。

<code>#!/bin/bashfor i in $(ls *.sh | sort);do echo $(wc $i)done</code>

実行すると、各ファイルの統計情報が得られ、ファイルはアルファベット順にリストされます。

./command.sh

目を見張るような for ループ

forループは、汎用的で理解しやすいスクリプティング ツールです。しかし、柔軟であるにもかかわらず、他のループが存在するのには理由があることを忘れないでください。forループが必要なすべてであると考えるのはやめましょう。

例えば、whileループは、ファイルから行を読み取るなど、特定のことにforループよりもはるかに適しています。

優れたスクリプトを作成することは、手元のタスクに最も適したツールを使用することを意味します。forループは、トリックのツールボックスにあると便利なツールです。