順番に読み進めながら学べます

繰り返し — for でファイルを 1 件ずつ処理

この記事は、基礎コマンドからシェルスクリプトまでLinuxの実践的なスキルを1からマスターする「Linux入門講座の一部」です。
for f in *.txtでファイル一覧を回し、while [ "$i" -le 3 ]やuntilで条件付きに繰り返し、continueで空行をとばしbreakで上限到達時に打ち切る制御を、図解と端末で実習します。

リストを順に処理する — for

forは与えた値を 1 つずつ取り出して、同じ処理を繰り返します

for v in a b c; do ... doneの形で、vabcが順に入ります。

dodoneの間が繰り返す本体です。

値の並びは直接書くほか、*.txtのようなファイルパターンや$(...)のコマンド出力も使えます。

for f in *.txtと書くと、カレントディレクトリの.txtファイルが順にfに入り、ファイルごとの処理を書けます。

for line in $(cat list.txt)のように$(...)を使うと、コマンドの出力を反復対象にできます。

これにより、ファイル一覧の集計や複数ファイルの一括処理が書けます

for env in dev stg prod; do        # 並べた値を順に処理
  echo "deploying to $env"
done
for f in *.sh; do                  # .sh ファイルを順に処理
  echo "script: $f"
done
for のループの回り方
for f in *.txt本体を実行(do … done)次の要素 → fdone で終了尽きたらリストの数だけ繰り返す
forはリストから 1 件ずつfに取り出して本体を実行し、要素が尽きたらdoneで終わります。
書き方意味
for v in a b c; do … done並べた値を順に処理するfor v in dev stg prod; do echo $v; done
for f in *.txt; do …条件に合うファイルを順に処理for f in *.txt; do wc -l "$f"; done
for x in $(cmd); do …コマンド出力を順に処理for d in $(ls); do echo $d; done
do … doneループ本体の開始と終了for v in a b; do echo $v; done

ファイル一覧を回って件数を集計するスクリプトを作成します。

vi count-lines.shcount-lines.shを開き、iで挿入モードに入って、先頭に#!/bin/shを書いてください。

② スクリプト内で素材ファイルをいくつか作成し、forでファイルパターンを回して 1 ファイルずつ行数を数え、合計件数を表示する処理を書いてください。

Escを押し:wqで保存してから、実行権限を付けてください。

④ スクリプトを実行し、各ファイルと合計が表示されることを確認してください。

⑤ 書く内容に迷ったら、解答パネルの本文をコピーしてviの挿入モードに貼り付けられます。(正しく実行できれば解説が表示されます)

Linux console
0 / 3 実行済み
Loading Linux Terminal...

条件で繰り返す — while / until

whileは条件が真の間くり返します。

while [ "$i" -lt 3 ]; do ... doneのように、本体の中でカウンタを増やして終了に向かわせます。

untilは逆に、条件が真になるまで繰り返します

回数があらかじめ決まらない処理に向きます。

i=1
while [ "$i" -le 3 ]; do          # i が 3 以下の間くり返す
  echo "try $i"
  i=$((i + 1))
done                              # try 1 / try 2 / try 3
i=1
until [ "$i" -gt 3 ]; do          # 条件が真になるまで繰り返す
  echo "i=$i"
  i=$((i + 1))
done                              # i=1 / i=2 / i=3
while と until の違い
while [ i ≤ 3 ]条件は真本体を実行until [ i > 3 ]条件は偽本体を実行while: 真の間くり返すuntil: 真になるまで
whileは条件が真の間、untilは条件が真になるまで本体を繰り返します。どちらも本体でカウンタを進めて終了に近づけます。
書き方意味
while [ cond ]; do … done条件が真の間くり返すwhile [ "$i" -lt 3 ]; do …; done
until [ cond ]; do … done条件が真になるまでくり返すuntil [ -f done.flag ]; do …; done

回数を数えながら処理を繰り返す再試行スクリプトを作成します。

vi retry.shretry.shを開き、iで挿入モードに入って、先頭に#!/bin/shを書いてください。

② カウンタ変数を用意し、whileで上限まで繰り返しながら試行番号を表示し、本体の中でカウンタを増やす処理を書いてください。

③ 同じ処理をuntil [ "$i" -gt "$max" ]で書き換えても同じ結果になることを確かめてください。

Escを押し:wqで保存してから、実行権限を付けてください。

⑤ スクリプトを実行し、指定回数だけ繰り返したことを確認してください。

⑥ 書く内容に迷ったら、解答パネルの本文をコピーしてviの挿入モードに貼り付けられます。

Linux console
0 / 3 実行済み
Loading Linux Terminal...

forで制御する — break / continue

forで一覧を回す途中でも、breakcontinueで流れを変えられます。

continueはその回の残りをとばして次の要素へ進み、breakはループ自体を終了します。

if [ 条件 ]; then continue; fiif [ 条件 ]; then break; fiの形で条件と組み合わせ、不要な要素はとばす・目的の件数で打ち切るといった制御ができます。

for n in 1 2 3 4 5; do
  if [ "$n" -eq 3 ]; then continue; fi  # 3 はとばす
  if [ "$n" -eq 5 ]; then break; fi     # 5 で抜ける
  echo "n=$n"
done                                    # n=1 / n=2 / n=4
for の break / continue の流れ
n=1本体を実行n=1 を出力n=2本体を実行n=2 を出力n=3continue残りをとばし次へn=4本体を実行n=4 を出力n=5breakループ終了次の要素へcontinue: その回をとばすbreak: ループを抜ける
forn=1から順に本体を実行します。n=3continueで残りをとばして次へ進み、n=5breakでループ自体を終了します(出力は n=1 / n=2 / n=4)。
書き方意味
continueその回をとばし次の繰り返しへif [ -z "$x" ]; then continue; fi
breakループを途中で抜けるif [ "$n" -gt 100 ]; then break; fi

空行をとばしつつ上限で打ち切る集計スクリプトを作成します。

vi collect.shcollect.shを開き、iで挿入モードに入って、先頭に#!/bin/shを書いてください。

② 値の並びをforで回し、空または不要な値はcontinueでとばし、上限に達したらbreakでループを抜ける処理を書いてください。

Escを押し:wqで保存してから、実行権限を付けてください。

④ スクリプトを実行し、とばした値と打ち切った位置を確認してください。

⑤ 書く内容に迷ったら、解答パネルの本文をコピーしてviの挿入モードに貼り付けられます。

Linux console
0 / 3 実行済み
Loading Linux Terminal...

whileで制御する — break / continue

whileの条件判定に加えて、breakcontinueを使うと途中での打ち切りや読み飛ばしができます。

continueはその回をとばして条件判定へ戻りbreakは条件を待たずにループを抜けます。

このとき、カウンタの更新を本体の先頭(continueより前)に置かないと、とばした回で更新されず終わらなくなる点に注意します。

i=0
while [ "$i" -lt 10 ]; do
  i=$((i + 1))                          # 先頭で進める
  if [ "$i" -eq 3 ]; then continue; fi  # 3 回目はとばす
  if [ "$i" -eq 6 ]; then break; fi     # 6 回目で抜ける
  echo "attempt $i"
done                                    # attempt 1 / 2 / 4 / 5
while の break / continue の流れ
i=1本体を実行attempt 1i=2本体を実行attempt 2i=3continue条件判定へ戻るi=4本体を実行attempt 4i=5本体を実行attempt 5i=6breakループ終了次の回へcontinue: 条件判定へ戻るbreak: ループを抜ける
whileは条件が真の間、iを 1 ずつ進めて本体を実行します。i=3continueは条件判定へ戻り、i=6breakは条件を待たずにループを終了します(出力は attempt 1 / 2 / 4 / 5)。
書き方意味
continueその回をとばし条件判定へ戻るif [ $((i % 3)) -eq 0 ]; then continue; fi
break条件を待たずにループを抜けるif [ "$found" -ge 4 ]; then break; fi
カウンタ更新の位置continueより前で更新するi=$((i + 1))を本体の先頭に置く

whileで回しながら不要な回をとばし、必要な件数で打ち切るスキャンスクリプトを作成します。

vi scan.shscan.shを開き、iで挿入モードに入って、先頭に#!/bin/shを書いてください。

② カウンタを用意してwhileで上限まで回し、本体の先頭でカウンタを 1 進めてください。

③ 特定の条件に当てはまる回はcontinueでとばし、必要な件数に達したらbreakでループを抜ける処理を書いてください。

Escを押し:wqで保存してから、実行権限を付けてください。

⑤ スクリプトを実行し、とばした回と打ち切った位置を確認してください。

⑥ 書く内容に迷ったら、解答パネルの本文をコピーしてviの挿入モードに貼り付けられます。

Linux console
0 / 3 実行済み
Loading Linux Terminal...
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1for f in *.txt; do ... doneは何を繰り返しますか?

Q2条件が真の間くり返すのはどのキーワードですか?

Q3その回だけとばして次の繰り返しに進むのはどれですか?