シェルスクリプトでは、単にコマンドを実行するだけではなく、条件によって処理を変えたり、繰り返し処理を行ったり、また、通常のコマンドのように引数を受け取って、引数に応じた処理を行ったりすることができます。前回に続き、今回もシェルスクリプトで「引数」を扱う方法を解説します。
前回作成したシェルスクリプト「grepall」は、引数で「検索文字列」「ファイル名」「検索する場所」を、この順番で指定するという想定でした。
今回は、このgrepallを加工して、「場所が指定されていなかったら、カレントディレクトリを探す」ようにしてみましょう。
「場所」は3つ目の引数なので、まずは引数の個数が3つだったときにだけ、grepコマンドを実行するようにしてみます。具体的には、grepコマンドの前に2行、後ろに1行追加します。また、読みやすくするために、grepの前に空白を追加しています。
なお、判定に使用している「if」文の書き方については、次回「制御構文」であらためて取り上げます。今の段階では、空白の有無や改行の位置はサンプル通りにしておいてください。
#! /bin/bash if [ $# = 3 ] then grep -Hn -e "$1" -r --include="$2" "$3" fi
【※】if文の「[ ]」および「=」の前後には空白が必要です。ここでは個数を見ていることを分かりやすくするために引用符(")を省略していますが、「if [ "$#" = "3" ]」と書いても構いません。
次に、「3つ目の引数を省略したらカレントディレクトリ下を探す」という動作ができるようにしてみましょう。
先ほどの「引数が3つだったらgrepコマンドを実行」というブロックに、「2つだったら〜」という処理を追加するには次のようにします。
#! /bin/bash if [ $# = 3 ] then grep -Hn -e "$1" -r --include="$2" "$3" elif [ $# = 2 ] then grep -Hn -e "$1" -r --include="$2" "." fi
先ほどの書き方だと、スクリプトの中で「grep -Hn -e "$1" -r --include="$2"」が2回登場することになります。そこで、「引数が指定されているかどうかに応じて、引数の内容をいったん変数に保存する」という書き方にしてみましょう。少々長くなりますが、スクリプトの中でgrepコマンドを書くのが1回になり、後でgrepコマンドのオプションを変更したくなった場合でも修正が1箇所で済むようになります。
ここでは、2つ目の引数が指定されていない場合は検索対象を「*」で全てのファイルに、3つ目の引数が指定されていない場合は検索場所を「.」でカレントディレクトリにするようにしています。
なお、変数を設定するときの「=」には、前後の空白を入れることができない点に注意してください。
#! /bin/bash if [ -n "$1" ] #1つ目の引数が指定されている?(※) then ptn="$1" #指定されていれば変数ptnに保存 else exit #指定されていなかったら終了 fi if [ -n "$2" ] #2つ目の引数が指定されている? then file="$2" #指定されていれば変数fileに保存 else file="*" #指定されていなかったら"*"(全てのファイル)を対象にする fi if [ -n "$3" ] #3つ目の引数が指定されている? then dir="$3" #指定されていれば変数dirに保存 else dir="." #指定されていなかったらカレントディレクトリを対象にする fi grep -Hn -e "$ptn" -r --include="$file" "$dir"
【※】「if [ -n "$1" ]」は“$1が空白ならば”という意味で、「-n」や引用符を省略して「if [ $1 ]」のように書くこともできます。
シェルスクリプトを試しているとき、変数の内容が意図した通りになっているかどうかを確認したい場合は、スクリプトの中で「echo」コマンドを使って確かめてみましょう。
例えば、先ほどのgrepallでgrepの行の前に、以下のような行を追加します。
(中略) echo "ptn:$ptn file:$file dir:$dir" #変数の内容を確認 grep -Hn -e "$ptn" -r --include="$file" "$dir"
$ ./grepall diary *.txt . ptn:diary fie:*.txt dir:. ← 追加したecho行の結果 memo.txt:3:my diary ← grepの実行結果 ……
Copyright © ITmedia, Inc. All Rights Reserved.