Q1n=$(grep -c error log.txt)は変数 n に何を入れますか?
コマンド連携 — grep / awk の結果で分岐する
この記事は、基礎コマンドからシェルスクリプトまでLinuxの実践的なスキルを1からマスターする「Linux入門講座の一部」です。
スクリプト内でn=$(grep -c ERROR access.log)で件数を変数化し、total=$(awk '{s+=$1} END{print s}')で合計を取り、if [ "$n" -ge 2 ]で分岐するスキャナを、図解とブラウザ端末で作ります。
スクリプトの中でコマンドを呼ぶ — パイプとコマンド置換
シェルスクリプトの本当の力は、grep awk sed sort wcといった一般コマンドをスクリプト内で組み合わせられる点にあります。
スクリプトの中でもパイプ|でコマンドをつなぎ、$(cmd)のコマンド置換でその出力を取り込めます。
n=$(grep -c error log.txt)と書くと、grep -cが出した一致行数を変数nに入れられます。
total=$(awk '{s+=$1} END{print s}' f)のように集計結果を変数にすることもできます。
コマンドの結果を変数にすると、その値を使ってスクリプトの動きを変えられます。
printf 'INFO ok\nERROR disk\nINFO ok\nERROR cpu\n' > sys.log # 素材を作成
vi count.sh # エディタで開き、次の内容を書いて :wq で保存
# #!/bin/sh
# n=$(grep -c ERROR sys.log)
# echo "ERROR の件数: $n"
chmod +x count.sh
./count.sh # ERROR の件数: 2
grep -cで数えた件数を変数nにし、ifで 2 件以上なら警告、そうでなければ正常に分岐します。| 書き方 | 意味 | 例 |
|---|---|---|
n=$(grep -c pat f) | 一致した行数を変数 n に入れる | n=$(grep -c error log.txt) |
$(cmd | cmd) | パイプの結果を変数に取り込む | top=$(sort log.txt | head -1) |
if [ "$n" -ge 2 ]; then … | 件数が2件以上かで条件分岐する | if [ "$n" -ge 2 ]; then echo warn; fi |
集計して結果で動きを変える — awk と分岐
件数だけでなく、数値を合計して判定することもできます。
total=$(awk '{s+=$1} END{print s}' f)は各行の1列目を足し合わせ、その合計を変数totalに入れます。
同じ語ごとの出現数を数えたいときはsort f | uniq -cで並べ替えてから数え、その結果を$(...)で取り込むこともできます。
得られた合計をif [ "$total" -gt 100 ]; then …のようにしきい値と比べれば、「合計が一定を超えたら警告」といった判定ができます。
集計と分岐を1つのスクリプトにまとめると、データを読んで状況を判断する実用的なツールになります。
printf '40\n30\n50\n' > sales.txt # 1 列の数値データ
vi sum.sh # エディタで開き、次の内容を書いて :wq で保存
# #!/bin/sh
# total=$(awk '{s+=$1} END{print s}' sales.txt)
# if [ "$total" -gt 100 ]; then
# echo "合計 $total: 目標達成"
# else
# echo "合計 $total: 未達"
# fi
chmod +x sum.sh
./sum.sh # 合計 120: 目標達成
printf 'a\na\nb\n' > tags.txt # 同じ語が並ぶ素材
sort tags.txt | uniq -c # 並べ替えてから件数を数える
# 出力:
# 2 a
# 1 b
awkで合計したtotalをifでしきい値 20 と比べ、超えたら要対応、以内なら許容内に分岐します。| 書き方 | 意味 | 例 |
|---|---|---|
awk '{s+=$1} END{print s}' f | 1列目を合計して集計 | awk '{s+=$1} END{print s}' nums.txt |
sort f | uniq -c | 集計前に並べ替えて件数を数える | sort tags.txt | uniq -c |
if [ "$total" -gt N ]; then … | 合計をしきい値 N と比べて分岐 | if [ "$total" -gt 100 ]; then … |
出力とエラーを振り分ける — > と 2>
スクリプトの結果を画面ではなくファイルに残したいことがあります。
./scan.sh > report.txtは通常の出力(標準出力)をreport.txtに書き込みます。
echo "..." 1>&2のようにエラーメッセージを標準エラーへ出しておけば、./scan.sh > report.txt 2> error.logで正常な結果とエラーを別ファイルに分けられます。
vi job.sh # エディタで開き、次の内容を書いて :wq で保存
# #!/bin/sh
# echo "処理を開始しました" # 標準出力
# echo "注意: 入力が空でした" 1>&2 # 標準エラー
chmod +x job.sh
./job.sh > out.txt 2> err.txt # 出力とエラーを別ファイルへ
cat out.txt # 処理を開始しました
cat err.txt # 注意: 入力が空でした
> report.txt、標準エラーは2> error.logと別々に振り分けられます。| 書き方 | 意味 | 例 |
|---|---|---|
cmd > out | 標準出力をファイルに書き込む | ./scan.sh > report.txt |
echo "…" 1>&2 | メッセージを標準エラーへ出す | echo "failed" 1>&2 |
cmd > out 2> err | 出力とエラーを別ファイルに振り分け | ./scan.sh > report.txt 2> error.log |
理解度チェック
まずは1問ずつ答えてみましょう。
Q2if [ "$n" -ge 2 ]; then …は何をしますか?
Q3./scan.sh > report.txt 2> error.logの2>は何を振り分けますか?