【Shell】指定したディレクトリ内に存在する複数のファイルから文字列を検索する

■作成するプログラムの概要

モジュール実行時に「検索文字列」と「検索対象ディレクトリ」を指定する。
指定した「検索対象ディレクトリ」内に存在する複数ファイルについて、「検索文字列」が存在するか、確認する。
存在していた場合、アウトプットとしてファイル名と文字列を出力する。

■フローチャート

■プログラム仕様

インプット処理内容アウトプット
実行モジュール名を変数にセットする。
【第1引数】
検索文字列
【第2引数】
ディレクトリパス
「検索文字列」と「ディレクトリパス」を変数にセットする。
【条件分岐】
「検索文字列」について、
▼存在する場合
何もしない(後続の処理を実行する)。
▼存在しない場合
エラーメッセージを出力する。
処理を終了する(異常終了)。
【メッセージ】
エラーメッセージ
【条件分岐】
「ディレクトリパス」について、
▼第2引数に指定している場合
何もしない(後続の処理を実行する)。
▼第2引数に指定していない場合
カレントディレクトリを変数にセットする。
【条件分岐】
「ディレクトリパス」について、
▼サーバに存在する
文字列の検索を実施する。
検索結果を出力する。・・・①
▼サーバに存在しない
エラーメッセージを出力する。
処理を終了する(異常終了)。・・・②
【メッセージ】
①検索結果
②エラーメッセージ

■実行環境のディレクトリ構造

■テキストファイルの内容

・tmp1.txt

hello world!
I like soccer.

・tmp2.txt

hello world!
I like baseball.

・tmp3.txt

hello world!
I like basketball.

■サンプルコード

#!/bin/bash

# 実行モジュール名を取得
readonly MODULE_NAME=${0##*/}

# 実行引数を取得
#   第1引数:検索文字列
#   第2引数:検索ディレクトリ名
search_word=$1
search_directory=$2


# 検索文字列入力チェック:文字数が0ならエラー
if [[ -z ${search_word} ]]
then
    printf '%s\n' "${MODULE_NAME}:検索文字が指定されていません。" 1>&2
    exit 1
fi

# 検索ディレクトリ名が省略された場合は、カレントディレクトリを対象にする。
if [[ -z ${search_directory} ]]
then
    printf '%s\n' "${MODULE_NAME}:検索ディレクトリが省略されました。" 1>&2
    printf '%s\n' "${MODULE_NAME}:カレントディレクトリを検索対象にします。" 1>&2
    printf '%s\n' "${MODULE_NAME}:パス:$PWD" 1>&2
    search_directory=.
fi

# 検索対象ディレクトリが存在するかチェック
if [[ ! -d ${search_directory} ]]
then
    printf '%s\n' "${MODULE_NAME}:ディレクトリが存在しません。" 1>&2
    printf '%s\n' "${MODULE_NAME}:パス:${search_directory}" 1>&2
    exit 2
fi

# 検索対象ディレクトリからファイルを取得し、
# 各ファイルについて、検索文字列が存在するか確認する。
printf '%s\n' "########## 検索結果 ##########"
find -- "${search_directory}" -type f -print0 | \
xargs -0 grep -e "${search_word}" -- /dev/null

■実行結果

$ ./sample.sh hello
sample.sh:検索ディレクトリが省略されました。
sample.sh:カレントディレクトリを検索対象にします。
sample.sh:パス:/work
########## 検索結果 ##########
./tmp/tmp1.txt:hello world!
./tmp/tmp3.txt:hello world!
./tmp/tmp2.txt:hello world!


$ ./sample.sh hoge
sample.sh:検索ディレクトリが省略されました。
sample.sh:カレントディレクトリを検索対象にします。
sample.sh:パス:/work
########## 検索結果 ##########


$ ./sample.sh baseball ./tmp
########## 検索結果 ##########
./tmp/tmp2.txt:I like baseball.

 
$ ./sample.sh baseball 
sample.sh:検索ディレクトリが省略されました。
sample.sh:カレントディレクトリを検索対象にします。
sample.sh:パス:/work
########## 検索結果 ##########
./tmp/tmp2.txt:I like baseball.


$ ./sample.sh
sample.sh:検索文字が指定されていません。


$ ./sample.sh bb ./tmp
########## 検索結果 ##########


$ ./sample.sh baseball ./hoge
sample.sh:ディレクトリが存在しません。
sample.sh:パス:./hoge
タイトルとURLをコピーしました