シェルスクリプトの基礎 - 繰り返し文

提供:MochiuWiki : SUSE, EC, PCB
2020年5月31日 (日) 17:40時点におけるWiki (トーク | 投稿記録)による版 (Wiki がページ「繰り返し文(シェルスクリプト)」を「シェルスクリプトの基礎 - 繰り返し文」に、リダイレクトを残さずに移動しました)
ナビゲーションに移動 検索に移動

概要

繰り返し文は、変数にリストで指定した値を順番に代入し、その度にdoからdoneまでの処理を実行し、
リストの値を全てを代入し処理が完了したら繰り返しは終了となる。


for文

変数iに1から5までの数字を指定して、変数に代入された値をechoで表示させるというサンプルコードを以下に記述する。

 #!/bin/bash
 
 for i in 1 2 3 4 5
 do
    echo $i
 done


# 出力
1
2
3
4
5



for文におけるリストの指定

リストの指定方法を以下に記載する。

コマンドの実行結果の使用

リスト部分には、コマンドの実行結果を値として使用でき、その場合は、コマンドをバッククォート(`)で囲む必要がある。

 #!/bin/bash
 
 for file in `ls /var/log/messages*`
 do
    echo $file
 done


# 出力
/var/log/messages
/var/log/messages-20170618
/var/log/messages-20170626
/var/log/messages-20170702
/var/log/messages-20170710


また、bashの場合は、$()も使用できる。

 #!/bin/bash
 
 for file in $(ls /var/log/messages*)
 do
    echo $file
 done


seqコマンドの使用

seqコマンドは、指定した開始の数値から終わりの数値までを表示するというコマンドで、繰り返す回数を指定することができる。
例えば、1から5までをリストとして指定する場合は、seq 1 5と指定する。
また、開始が1からの場合は、開始の数値を省略することもできる。

seq 1 5
または
seq 5
または
seq 1 1 5


seqコマンドを使用して、1から5までを範囲指定して、ファイルを作成するというスクリプトを記述する。
file_1からfile_5までのファイルが作成される。

 #!/bin/bash
 
 for data in `seq 5`
 do
    touch file_$data
 done


また、wオプションを使用して、ゼロパディングすることもできる。

# 01から10までを出力する
seq -w 1 10


ブレーズ展開

bashの場合、ブレーズ展開機能を使用してリストを指定することもできる。
ブレーズ展開は、{開始..最後}といった形式で指定することで、簡単に範囲を指定することができる。

例えば、{1..5}で1から5を指定する場合、以下のように記述する。

 #!/bin/bash
 
 for i in {1..5}
 do
    echo $i
 done


算術式の使用

bashの場合、以下のように、1から5までを指定することもできる。

 #!/bin/bash
 
 for ((i=1; i<6; i++))
 do
    echo $i
 done


ファイルの読み込み

事前にリストに読み込ませるファイルを作成しておき、catコマンド等でファイルの中身を読み込むという方法ある。
list.txtファイルを事前に作成して、catコマンドでファイルの中身を読み込む。

 #!/bin/bash
 
 for i in `cat list.txt`
 do
    echo $i
 done


コマンドライン引数の使用

リスト部分に"@$"を使用すると、シェルスクリプトを実行する際の引数を、リストの値にすることができる。

 #!/bin/bash
 
 for i in "$@"
 do
    echo $i
 done


配列変数の使用

配列を使用してリストを指定することもできる。
配列arrayに1から5を設定して、それをリスト部分で呼び出す。

 #!/bin/bash
 
 array=(1 2 3 4 5)
 for i in ${array[@]}
 do
    echo $i
 done



while文

以下のサンプルコードでは、変数iが6より小さい間だけ、変数iに代入された値をechoで表示した後、
exprコマンドを使用して変数iに1を加算する。

 #!/bin/bash
 
 i=1
 while [ $i -lt 6 ]
 do
    echo "$i"
    i=`expr $i + 1`
 done


# 出力
1 2 3 4 5


bashのみだが、exprコマンドは遅いので(())を使用した算術式の方が処理が速い。

 #!/bin/bash
 
 i=1
 while ((i < 6))
 do
    echo $i
    i=$(( i + 1 ))
 done



while文における条件の指定

条件の指定にはtestコマンド(または[]コマンド)を使用する場合が多いが、それ以外も条件として指定することができる。

ファイルから読み込む

readコマンドを使用してlist.txtファイルの内容を読み込み、1行ずつ表示させる。
以下のシェルスクリプトを実行すると、list.txtファイルの内容を1行ずつ読み込み、その内容が表示される。

# list.txtファイルの内容
abc
def
ghi


 #!/bin/bash
 
 while read line
 do
    echo "$line"
 done < ./list.txt


# 出力
abc
def
ghi


無限ループ

条件にNULLコマンドである:(コロン)を指定すると、無限ループになる。
NULLコマンド:は、何もせずに終了コード0(真)を返すので、条件が常に真となるため、無限ループになる。
無限ループを終了させるには、Ctrlキー + Cキーで強制的に終了させるか、
処理部分でif文またはcase文などの条件分岐で、break、return、exitコマンドを実行する。

 while :
 do
    # 処理
 done


以下のシェルスクリプトに、無限ループにcase文(条件分岐)を組み込む。

"Repeat? (y/n) :"の表示後、yキーを入力すると"Repeat!"と表示して処理が繰り返され、
nキーを入力すると、"Repeat end."と表示して処理を終了させる。

yキーまたはnキー以外のキーを入力すると、"Push y or n key."と表示して、
yキーまたはnキーのいずれかを入力するように促すメッセージを表示して処理を繰り返す。

 #!/bin/bash
 
 while :
 do
    read -p "Repat? (y/n) :" key
    case "$key" in
       y) echo "Repeat!";;
       n) echo "Repeat end."
          break ;;
       *) echo "Push y or n key.";;
    esac
 done


# 出力
Repeat? (y/n) :q   ← yキーまたはnキー以外を入力
Push y or n key.
Repat? (y/n) :y    ← yキーを入力
Repeat!
Repat? (y/n) :n    ← nキーを入力
Repeat end.