awk の基本概念
awk
は強力なパターンスキャニングおよびデータ抽出言語です。テキストファイルを行単位で処理し、各行をフィールドに分割して処理できます。
awk の基本構文
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 基本的な構文
awk 'pattern { action }' file
# パターンなし(全行が対象)
awk '{ print }' fruits.txt
# アクションなし(マッチした行を印刷)
awk '/apple/' fruits.txt
# パターンとアクション
awk '/apple/ { print $1, $2 }' fruits.txt
awk の処理単位:
- レコード: 通常は1行(RS で変更可能)
- フィールド: 空白で区切られた各部分(FS で変更可能)
- $0: レコード全体
- $1, $2, ...: 各フィールド
- NF: フィールド数
- NR: レコード番号
組み込み変数
フィールドとレコード関連
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# フィールド変数
awk '{ print $1 }' fields.txt # 最初のフィールド
awk '{ print $NF }' fields.txt # 最後のフィールド
awk '{ print $(NF-1) }' fields.txt # 最後から2番目
# レコード情報
awk '{ print NR, NF, $0 }' fields.txt # 行番号、フィールド数、全体
# フィールドの動的アクセス
awk '{ for(i=1; i<=NF; i++) print i, $i }' fields.txt
区切り文字の設定
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# フィールド区切り文字(FS)の設定
awk -F, '{ print $1, $3 }' fruits.csv # コンマ区切り
awk 'BEGIN { FS="," } { print $1, $3 }' fruits.csv # BEGIN で設定
# 出力フィールド区切り文字(OFS)
awk -F, 'BEGIN { OFS=" | " } { print $1, $2, $3 }' fruits.csv
# 出力レコード区切り文字(ORS)
awk 'BEGIN { ORS=" --- " } { print $1 }' fruits.txt
その他の重要な変数
# ファイル名
awk '{ print FILENAME, $0 }' fruits.txt
# レコード区切り文字
awk 'BEGIN { RS=";" } { print NR, $0 }' data_with_semicolons.txt
# パターンマッチ情報
awk '/apple/ { print "Found at line", NR }' fruits.txt
演算子と式
算術演算子
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 基本的な算術演算
awk '{ print $1 + $2 }' numbers.txt # 加算
awk '{ print $1 - $2 }' numbers.txt # 減算
awk '{ print $1 * $2 }' numbers.txt # 乗算
awk '{ print $1 / $2 }' numbers.txt # 除算
awk '{ print $1 % $2 }' numbers.txt # 剰余
awk '{ print $1 ** $2 }' numbers.txt # 冪乗
# インクリメント・デクリメント
awk '{ print ++$1, $2-- }' numbers.txt
# 複合代入演算子
awk '{ total += $1 } END { print "Total:", total }' numbers.txt
比較演算子
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 数値比較
awk '$2 > 5 { print $1 }' items.txt # 5より大きい
awk '$2 <= 4 { print $1 }' items.txt # 4以下
awk '$2 == 5 { print $1 }' items.txt # 5と等しい
awk '$2 != 3 { print $1 }' items.txt # 3と等しくない
# 文字列比較
awk '$1 > "c" { print $1 }' items.txt # "c"より大きい(辞書順)
awk '$1 == "apple" { print $2 }' items.txt
論理演算子
# AND (&&)
awk '$2 > 3 && $2 < 8 { print $1 }' items.txt
# OR (||)
awk '$2 < 4 || $2 > 7 { print $1 }' items.txt
# NOT (!)
awk '!($2 > 5) { print $1 }' items.txt
正規表現演算子
# マッチ (~)
awk '$1 ~ /^a/ { print $1 }' items.txt # aで始まる
awk '$1 ~ /e$/ { print $1 }' items.txt # eで終わる
# 非マッチ (!~)
awk '$1 !~ /a/ { print $1 }' items.txt # aを含まない
# 動的な正規表現
awk 'BEGIN { pattern="^[ag]" } $1 ~ pattern { print $1 }' items.txt
制御構造
if 文
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 単純な if 文
awk '{ if ($2 > 5) print $1, "high stock" }' inventory.txt
# if-else 文
awk '{ if ($2 > 5) print $1, "high"; else print $1, "low" }' inventory.txt
# 複数条件の if-else
awk '{
if ($2 > 7) print $1, "very high"
else if ($2 > 4) print $1, "medium"
else print $1, "low"
}' inventory.txt
# 複雑な条件
awk '{
if ($2 > 5 && $3 == "red")
print $1, "high red stock"
else if ($2 < 3)
print $1, "reorder needed"
}' inventory.txt
for ループ
# C形式のforループ
awk '{
for (i = 1; i <= $2; i++)
printf "%s ", $1
print ""
}' inventory.txt
# フィールドを反復
awk '{
for (i = NF; i >= 1; i--)
printf "%s ", $i
print ""
}' inventory.txt
# 配列の反復(後で詳しく説明)
awk '{
for (field in $0)
print field, $field
}' inventory.txt
while ループ
# while ループの例
awk '{
i = 1
while (i <= $2) {
printf "%s[%d] ", $1, i
i++
}
print ""
}' inventory.txt
# do-while ループ(GNU awk)
awk '{
i = 1
do {
printf "%s ", $1
i++
} while (i <= $2)
print ""
}' inventory.txt
配列
連想配列の基本
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 配列への値の格納
awk '{
total[$2] += $3
} END {
for (item in total)
print item, total[item]
}' transactions.txt
# 多次元配列(連想配列のシミュレート)
awk '{
key = $1 SUBSEP $2 # SUBSEP は配列のインデックス区切り
data[key] += $3
} END {
for (combo in data)
print combo, data[combo]
}' transactions.txt
# 配列のソート(GNU awk)
awk '{
count[$1]++
} END {
PROCINFO["sorted_in"] = "@val_num_desc"
for (item in count)
print item, count[item]
}' transactions.txt
配列の操作
# 配列の要素の削除
awk 'BEGIN {
a[1] = "one"
a[2] = "two"
a[3] = "three"
delete a[2]
for (i in a) print i, a[i]
}'
# 配列全体の削除
awk 'BEGIN {
delete a # 配列全体を削除
}'
# 配列のサイズ(GNU awk)
awk '{
items[$1] = $2
} END {
print "Array size:", length(items)
}' inventory.txt
組み込み関数
文字列関数
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# length() - 文字列の長さ
awk '{ print $0, "length:", length($0) }' strings.txt
# substr() - 部分文字列
awk '{ print substr($1, 1, 3) }' strings.txt # 1文字目から3文字
# index() - 文字列の位置
awk '{ print index($0, "is") }' strings.txt
# tolower(), toupper() - 大文字小文字変換
awk '{ print tolower($0) }' strings.txt
awk '{ print toupper($1) }' strings.txt
# gsub(), sub() - 置換
awk '{ gsub(/[aeiou]/, "*"); print }' strings.txt # 母音を*に
awk '{ sub(/[A-Z]/, "[&]"); print }' strings.txt # 最初の大文字を[]で囲む
# split() - 文字列の分割
awk '{
n = split($0, words, " ")
for (i = 1; i <= n; i++)
print i, words[i]
}' strings.txt
数学関数
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 基本的な数学関数
awk '{
print "Original:", $1
print "int:", int($1)
print "sqrt:", sqrt($1)
print "sin:", sin($1)
print "cos:", cos($1)
print "exp:", exp($1)
print "log:", log($1)
print "---"
}' math_data.txt
# random() 関数
awk 'BEGIN {
srand() # 乱数の種を設定
for (i = 1; i <= 5; i++)
print int(rand() * 100) + 1 # 1-100の乱数
}'
入出力関数
# printf() - 書式設定された出力
awk '{ printf "Item: %-10s Quantity: %3d\n", $1, $2 }' inventory.txt
# getline - 追加の入力読み込み
awk '{
print "Current line:", $0
if ((getline next_line) > 0)
print "Next line:", next_line
}' inventory.txt
# system() - システムコマンドの実行
awk '{ system("echo Processing: " $1) }' inventory.txt
パターンマッチング
BEGIN と END
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# BEGIN パターン(処理開始前)
awk 'BEGIN {
print "Starting data processing..."
total = 0
} {
total += $2
} END {
print "Total quantity:", total
print "Processing complete."
}' simple_data.txt
# 複数のBEGINとEND
awk 'BEGIN { print "Phase 1" }
BEGIN { print "Phase 2" }
{ count++ }
END { print "Processed", count, "lines" }
END { print "Finished" }' simple_data.txt
条件パターン
# 数値範囲のパターン
awk 'NR >= 2 && NR <= 4 { print "Middle:", $0 }' simple_data.txt
# フィールド値のパターン
awk '$2 > 4 { print "High quantity:", $1 }' simple_data.txt
# 複合パターン
awk '$1 ~ /^[ag]/ && $2 > 3 { print "Selected:", $1, $2 }' simple_data.txt
範囲パターン
# パターン範囲
awk '/banana/,/grape/ { print "In range:", $0 }' simple_data.txt
# 行番号範囲
awk 'NR==2, NR==4 { print "Lines 2-4:", $0 }' simple_data.txt
実践演習
演習1: 売上データの分析
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
以下の分析を行ってください:
- カテゴリ別の売上合計
- 日付別の取引件数
- 最高額の取引
- 平均取引額
解答例:
# 1. カテゴリ別売上合計
awk -F, '{
category_sales[$2] += $4
} END {
print "Category Sales:"
for (cat in category_sales)
printf " %s: $%d\n", cat, category_sales[cat]
}' sales.txt
# 2. 日付別取引件数
awk -F, '{
daily_count[$1]++
} END {
print "\nDaily Transaction Count:"
for (date in daily_count)
printf " %s: %d\n", date, daily_count[date]
}' sales.txt
# 3. 最高額の取引
awk -F, '{
if ($4 > max_amount) {
max_amount = $4
max_transaction = $0
}
} END {
print "\nHighest Transaction:"
print " " max_transaction " ($" max_amount ")"
}' sales.txt
# 4. 平均取引額
awk -F, '{
total += $4
count++
} END {
printf "\nAverage Transaction: $%.2f\n", total/count
}' sales.txt
演習2: ログファイルの解析
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
以下の統計を生成してください:
- ログレベル別の件数
- エラーメッセージの一覧
- 時間帯別の分布(時間別)
解答例:
# 総合分析
awk '{
# ログレベル別カウント
level_count[$3]++
# エラーメッセージの保存
if ($3 == "ERROR") {
error_messages[NR] = substr($0, index($0, $4))
}
# 時間帯別分析
hour = substr($2, 1, 2)
hour_count[hour]++
} END {
print "=== Log Level Summary ==="
for (level in level_count)
printf "%s: %d\n", level, level_count[level]
print "\n=== Error Messages ==="
for (line in error_messages)
print "Line " line ": " error_messages[line]
print "\n=== Hourly Distribution ==="
for (h in hour_count)
printf "%s:00: %d\n", h, hour_count[h]
}' server.log
まとめ
このレッスンでは、awk プログラミングの基礎を学びました:
- awk の基本構文と動作原理
- 組み込み変数とフィールド処理
- 演算子と式の使用法
- 制御構造(if、for、while)
- 配列と連想配列の活用
- 組み込み関数の使い方
- パターンマッチングの技法
awk は小さなプログラムを書くような感覚でテキスト処理ができる強力なツールです。
💡 次のレッスンでは、awk を使った高度なデータ処理と集計について学びます。