メインコンテンツへスキップ
レッスン 3 / 8推定時間: 30

awk プログラミング基礎

awk の基本構文から変数、制御構造、関数まで、データ処理に必要なプログラミング技術を習得します

このレッスンの学習目標

  • awk の基本構文と動作原理を理解する
  • 変数と演算子を使いこなす
  • 制御構造(if文、ループ)を活用できる
  • 組み込み変数と関数を理解する

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. カテゴリ別の売上合計
  2. 日付別の取引件数
  3. 最高額の取引
  4. 平均取引額

解答例:

# 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

以下の統計を生成してください:

  1. ログレベル別の件数
  2. エラーメッセージの一覧
  3. 時間帯別の分布(時間別)

解答例:

# 総合分析
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 を使った高度なデータ処理と集計について学びます。

さらに学習を続けるには

素晴らしい学習ペースです!次のレッスンに進むには、無料会員登録をお願いします。無料会員では各コース3レッスンまで学習できます。

無料で続きを学ぶ

各コース3レッスンまで学習可能

学習進捗の自動保存

コース修了証明書の発行