awkでファイル内の数を集計
awkコマンドでお手軽に計算をしてみましょう.
概要
awkコマンドで合計や平均を求める方法を説明します.
サンプルデータ
sar コマンドの結果↓を コマンドラインで解析してみましょう.
として,a.txt を作りました.
ファイルの中身は こんな感じ↓です.
# head a.txt
Linux 5.15.26 (debian) 03/07/2022 _x86_64_ (8 CPU)
02:20:48 AM CPU %user %nice %system %iowait %steal %idle
02:20:49 AM all 0.52 0.00 9.41 1.55 0.00 88.53
02:20:50 AM all 0.78 0.00 8.17 1.56 0.00 89.49
02:20:51 AM all 0.88 0.00 10.34 1.01 0.00 87.77
02:20:52 AM all 0.64 0.00 10.04 0.89 0.00 88.44
02:20:53 AM all 1.39 0.00 9.25 1.27 0.00 88.09
02:20:54 AM all 0.66 0.00 8.32 1.59 0.00 89.43
02:20:55 AM all 1.04 0.00 8.43 1.43 0.00 89.11
478行のファイルです
# wc a.txt
478 4291 38134 a.txt
全ての行を表示する
awk '{print}' < a.txt
で可能です.
実行例
# awk '{print}' < a.txt | head
Linux 5.15.26 (debian) 03/07/2022 _x86_64_ (8 CPU)
02:20:48 AM CPU %user %nice %system %iowait %steal %idle
02:20:49 AM all 0.52 0.00 9.41 1.55 0.00 88.53
02:20:50 AM all 0.78 0.00 8.17 1.56 0.00 89.49
02:20:51 AM all 0.88 0.00 10.34 1.01 0.00 87.77
02:20:52 AM all 0.64 0.00 10.04 0.89 0.00 88.44
02:20:53 AM all 1.39 0.00 9.25 1.27 0.00 88.09
02:20:54 AM all 0.66 0.00 8.32 1.59 0.00 89.43
02:20:55 AM all 1.04 0.00 8.43 1.43 0.00 89.11
CPU使用率が表示されている行のみを抽出する
awk '/[0-9]$/{print}' < a.txt
で可能です.
実行例
# awk '/[0-9]$/{print}' < a.txt | head
02:20:49 AM all 0.52 0.00 9.41 1.55 0.00 88.53
02:20:50 AM all 0.78 0.00 8.17 1.56 0.00 89.49
02:20:51 AM all 0.88 0.00 10.34 1.01 0.00 87.77
02:20:52 AM all 0.64 0.00 10.04 0.89 0.00 88.44
02:20:53 AM all 1.39 0.00 9.25 1.27 0.00 88.09
02:20:54 AM all 0.66 0.00 8.32 1.59 0.00 89.43
02:20:55 AM all 1.04 0.00 8.43 1.43 0.00 89.11
02:20:57 AM all 0.81 0.00 6.19 1.75 0.00 91.25
02:20:58 AM all 0.79 0.00 7.74 2.49 0.00 88.98
02:20:59 AM all 1.97 0.00 9.84 3.41 0.00 84.78
3行減ったので,475行です.
# awk '/[0-9]$/{print}' < a.txt | wc
475 4275 38000
grepを用いても可能です
%usrの列のみ抽出する
awk '/[0-9]$/{print $4}' < a.txt
で,可能です.
実行例
# awk '/[0-9]$/{print $4}' < a.txt | head
0.52
0.78
0.88
0.64
1.39
0.66
1.04
0.81
0.79
1.97
%usrの列の値の合計を求める
awk '/[0-9]$/{SUM+=$4}END{print SUM}' < a.txt
で,可能です.
結果
awk '/[0-9]$/{SUM+=$4}END{print SUM}' < a.txt
34792.8
%usrの列の値の平均を求める
awk '/[0-9]$/{SUM+=$4;CNT++}END{print SUM/CNT}' < a.txt
で,可能です.
結果
# awk '/[0-9]$/{SUM+=$4;CNT++}END{print SUM/CNT}' < a.txt
73.2479
残念ながら,これ↓では不可能です.
結果
NRは読み込んだ行数.
/[0-9]$/にマッチしない最初の3行も読み込むので,475行でなく,478行です.
grepを用いた方が分かりやすいかも知れません.
マッチしない3行は,grepで先に削除され,awkに渡されない.
「%usr列と%system列の値の和」の平均を求める
awk '/[0-9]$/{SUM+=$4+$6;CNT++}END{print SUM/CNT}' < a.txt
で,可能です.
結果
# awk '/[0-9]$/{SUM+=$4+$6;CNT++}END{print SUM/CNT}' < a.txt
89.2164
grepを用いた方が分かりやすいかも知れません.
「%usr列の値と%system列の値の和」が50以上の行の数を数える
awk '/[0-9]$/{if($4+$6>=50){CNT++}}END{print CNT}' < a.txt
で可能.
実行結果
# awk '/[0-9]$/{SUM+=$4+$6;CNT++}END{print SUM/CNT}' < a.txt
89.2164
同様にgrepを用いた方が分かりやすいかも知れません.