はじめに
1,000 通の手紙に署名しなければならない状況を想像してください。1 通なら簡単ですが、1,000 通となると退屈で手も痛くなります。プログラミングでは、このような退屈な繰り返し作業を避けたいものです。
そこで使うのが ループ です。ループを使うと、コンピューターに「リストの各項目に対して処理を繰り返す」または「条件が変わるまで処理を続ける」と指示できます。
コンピューターは繰り返し作業が得意で、人間は苦手です。そのため、ループは自動化の中心的な仕組みです。同じコマンドのパターンを何度も手動で実行しているなら、そこにはループを使える可能性があります。
この実験では、独自のデジタル作業ラインを作成します。
- カウンター:数を自動的に数えるループ(
forループ)。 - 作業担当者:複数のファイルを 1 つずつ処理するループ(ファイルを扱う
forループ)。 - 監視役:目標が達成されるまで処理を続けるループ(
whileループ)。
数値のループ(For ループ)
for ループはチェックリストのようなものです。項目のリストを用意し、そのリストの各項目に対して処理を実行します。
これは Unix 系システムで特に役立つ自動化パターンの 1 つです。コンピューターは小さな処理を正確に繰り返すことが得意なので、ループを使えば、同じコマンドを何度もコピーせずに、1 つの項目に対する作業を多数の項目へ拡張できます。
まずは、最も簡単なリストである数値から始めます。コンピューターに 1 から 5 まで数えさせます。
最初に、作業ディレクトリを確認します。
cd ~/project
num_loop.sh という名前のスクリプトを作成します。
nano num_loop.sh
次のコードを入力します。
#!/bin/bash
for i in {1..5}; do
echo "Number: $i"
done
作業ラインの仕組み:
for i in {1..5}:これは項目を供給する部分です。数値 1、2、3、4、5 を 1 つずつ変数$iに渡します。do:処理を開始します。echo ...:各項目に対して実行する具体的な処理です。done:現在の項目の処理を終了し、次の項目を取得します。
{1..5} の部分は、ブレース展開(brace expansion) と呼ばれる Bash の省略記法です。ループが開始される前に、Bash がこれを値のリストへ展開します。つまり、ループはあらかじめ用意されたリストを、1 項目ずつ処理しています。
保存(Ctrl+O)して終了(Ctrl+X)します。
スクリプトを実行可能にします。
chmod +x num_loop.sh
./num_loop.sh
次のように表示され、数値を数えていることを確認できます。
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
ファイルのループ(For ループ)
数を数えるだけでも楽しいですが、ファイルを処理できると実用性が高まります。for ループは、*.txt のようなワイルドカードと組み合わせると非常に強力です。スクリプトに「このフォルダー内で見つかったすべてのテキストファイルに対して、X を実行する」と指示できます。
作業フォルダーには、すでにサンプルのテキストファイルがいくつか用意されています。それらを見つけるスクリプトを作成しましょう。
file_loop.sh という新しいファイルを作成します。
nano file_loop.sh
次のコードを入力します。
#!/bin/bash
echo "Listing text files:"
for file in *.txt; do
echo "Found file: $file"
done
仕組み:
{1..5} のような数値ではなく、*.txt というパターンをループに渡しています。
Bash はフォルダー内を確認し、data1.txt や notes.txt のようにパターンに一致するすべてのファイルを見つけます。そして、それらを 1 つずつ $file という変数に渡します。
この一致処理は、ループ本体が実行される前に行われます。シェルは *.txt をファイル名のリストに展開し、for ループはそのリストを順番に処理します。そのため、シェルスクリプトではループと glob パターンを組み合わせると効果的です。
保存して終了します。
スクリプトを実行します。
chmod +x file_loop.sh
./file_loop.sh
次のような出力が表示されます。
Listing text files:
Found file: data1.txt
Found file: data2.txt
Found file: notes.txt
単に echo を使う代わりに、ファイルを移動する mv や、アーカイブを作成する zip を使ったらどうなるか想像してみてください。同じ 4 行のスクリプトで、10,000 個のファイルを数秒で処理できます。
条件付きループ(While ループ)
for ループは、数値やファイルなどのリストがある場合に便利です。しかし、リストがない場合はどうでしょうか。「何かが起こるまで処理を続けたい」場合はどうすればよいでしょうか。
この役割を担うのが while ループ です。これはサーモスタットに似ています。「部屋が寒い間は、暖房をつけ続ける」という動作です。
手動で 10 まで数えるスクリプトを作成しましょう。
while_loop.sh を作成します。
nano while_loop.sh
次のコードを入力します。
#!/bin/bash
counter=1
while [ $counter -le 10 ]; do
echo "Count: $counter"
((counter++))
done
サーモスタットの仕組み:
while [ $counter -le 10 ]:条件です。「カウンターは 10 以下か?」を確認します。- YES の場合:ループに入ります。
- NO の場合:停止します。
((counter++)):更新処理です。カウンターに 1 を加えます。重要:この行を忘れると、カウンターは永遠に 1 のままになり、スクリプトも永遠に実行され続けます。これは「無限ループ」と呼ばれます。
ここで、for と while の重要な違いが分かります。for ループは通常、シェルからあらかじめ処理対象の並びを受け取ります。一方、while ループは条件に依存しており、スクリプトの実行中に、その条件が適切に変化するよう更新する必要があります。
((counter++)) は Bash の算術構文です。シェルに counter を数値として扱い、1 増加させるよう指示します。シェルスクリプトでは、テキスト処理と簡単な算術処理を組み合わせることが多いため、この構文は頻繁に登場します。
保存して終了します。
スクリプトを実行します。
chmod +x while_loop.sh
./while_loop.sh
for ループと同じように数を数えますが、仕組みは異なります。for はリストを順番に処理し、while は条件に基づいて処理を続けます。
まとめ
最初の自動化エンジンを作成しました。
この実験では、次の仕組みを身につけました。
- チェックリスト(
for):{1..5}のように、定義済みの項目リストを処理する。 - バッチ処理(
for *.txt):ディレクトリ内のすべてのファイルを自動的に処理する。 - サーモスタット(
while):特定の目標または上限に達するまで処理を繰り返す。
これらのループは、スクリプトを支える基本的な仕組みです。手作業で 1,000 回クリックする作業を、コンピューターなら 1 秒で実行できる処理に変えてくれます。



