メインコンテンツへスキップ
中級10分で読める

awkでデータ処理を自動化

Linuxのawkコマンドを使って、テキストデータの抽出、集計、整形などのデータ処理を効率的に自動化する方法を実例を交えて詳しく解説します。

実践編awkデータ処理テキスト処理自動化

🎯 この記事で学べること

  • 1
    `awk`コマンドの基本的な使い方とフィールド抽出の方法をマスターできます
  • 2
    パターンマッチングと条件処理を使ったデータ抽出ができるようになります
  • 3
    数値計算、集計、統計処理の実装方法を身につけられます
  • 4
    BEGIN/ENDブロックや配列を使った高度なデータ処理を学べます
  • 5
    ログ解析、CSV処理、レポート生成などの実践的なスキルが使えるようになります

読了時間: 約10

データ処理の最強ツールに挑戦!

こんにちは!今回は、テキストデータ処理の最強ツールawkについて学んでいきましょう。

「CSVファイルの特定の列だけ集計したい」「ログファイルからエラー数をカウントしたい」「売上データからレポートを生成したい」そんな時、Excelを開いて手作業していませんか?

awkを使えば、こんなデータ処理がコマンド一つでできるんです!名前は開発者のAho、Weinberger、Kernighanの3人の頭文字から。まるで小さなプログラミング言語のような強力さを持っていますよ!

基本的な使い方

まずは基本構文を理解しよう

awk 'パターン { アクション }' [ファイル...]

この構文がawkの基本です。「パターンにマッチしたら、アクションを実行する」という意味ですね。

一番簡単な例:列を取り出す

awkの強みは、データを「列」で扱えることです。Excelのセルを指定するように、簡単に列を取り出せます:

# 2番目の列だけ表示!
$ awk '{print $2}' file.txt

$1は1列目、$2は2列目、$3は3列目...という具合です。$0は行全体を表しますよ!

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

データの構造を理解しよう

CSVファイルも簡単に扱える(-Fオプション)

「スペース区切りじゃなくて、カンマ区切りのデータなんだけど...」大丈夫です!区切り文字を指定できます:

# CSVファイルの1列目と3列目を表示
$ awk -F',' '{print $1, $3}' data.csv

-F','で「カンマで区切ってね」と指示しています。タブ区切りなら-F'\t'、コロン区切りなら-F':'です!

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には、とっても便利な組み込み変数が用意されています:

  • NF: Number of Fields(その行のフィールド数)
  • NR: Number of Records(何行目か)
  • FS: Field Separator(区切り文字)
  • OFS: Output Field Separator(出力時の区切り文字)
# 「何行目に何個のフィールドがあるか」を表示
$ awk '{print NR ":", NF, "fields"}' file.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

🎮 理解度チェック

Q1: awk '{print $2}' file.txtは何をしますか?

awk '{print $2}' file.txtは何をしますか?

条件を付けて貪くしく処理!

「この条件に合う行だけ」を処理する

awkの真骨頂は、条件処理です。「3列目が100以上のデータだけ」とか「errorを含む行だけ」のように、柔軟にフィルタリングできます:

# 3列目が100以上のデータを表示
$ awk '$3 >= 100 {print $0}' data.txt

# "error"を含む行だけ処理
$ awk '/error/ {print $0}' log.txt

$3 >= 100のように数値比較も、/error/のように文字列検索もできます。これがgrepよりも柔軟な理由です!

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 $0}' contacts.txt

# 2列目が数字だけの行を表示
$ awk '$2 ~ /^[0-9]+$/ {print $0}' data.txt

~は「マッチする」という意味です。$2 ~ /pattern/なら2列目がパターンにマッチするかチェックできます!

計算も集計もお手の物!

数値の計算ができる!

awkのすごいところは、計算機のように使えることです。合計、平均、最大値...何でも計算できます:

# 2列目の合計を計算
$ awk '{sum += $2} END {print "Total:", sum}' numbers.txt

# 平均も簡単!
$ awk '{sum += $2; count++} END {print "Average:", sum/count}' data.txt

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

🎮 理解度チェック

Q2: awk -F',' '{print $1, $3}' data.csv-F','の役割は?

awk -F',' '{print $1, $3}' data.csvの-F','の役割は?

統計処理もバッチリ

最大値や最小値のような統計処理もできます:

# 最大値と最小値を求める
$ awk 'BEGIN {max=0; min=999999} 
       {if($2>max) max=$2; if($2<min) min=$2} 
       END {print "Max:", max, "Min:", min}' data.txt

特別なブロック:BEGINとEND

BEGIN:最初に一度だけ実行

BEGINENDは、awkの特別なブロックです。レポートのヘッダーやフッターを作る時に便利ですよ:

$ awk 'BEGIN {print "=== 売上レポート ==="} 
       {print $0} 
       END {print "=== レポート終了 ==="}' sales.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

END:最後に集計結果を表示

配列を使えば、カテゴリ別の集計も簡単です:

# 商品別の売上合計
$ awk '{sum[$1] += $2} END {for (item in sum) print item ":", sum[item]}' category_sales.txt

sum[$1]は連想配列です。1列目の値をキーにして、2列目の値を加算していきます。ExcelのSUMIF関数みたいですね!

実践的な使い方を見てみよう!

Webサーバーのアクセスログ解析

実際の仕事でよく使うパターンを紹介します:

# 404エラー(ページが見つからない)の数をカウント
$ awk '$9 == 404 {count++} END {print "404 errors:", count}' access.log

# どのIPから何回アクセスがあったか
$ awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log
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

CSVファイルをサクッと処理

Excelを開かなくても、CSVファイルを分析できます:

# ヘッダーを飛ばして、3列目の合計を計算
$ awk -F',' 'NR>1 {sum += $3} END {print "Total:", sum}' sales.csv

# 4列目が1000を超える商品だけ表示
$ awk -F',' '$4 > 1000 {print $1, $4}' products.csv

NR>1は「2行目以降」という意味です。CSVのヘッダー行をスキップする定番テクニック!

きれいなレポートを生成

awkを使えば、見た目も美しいレポートが作れます:

# フォーマットされた売上レポート
$ awk 'BEGIN {
         printf "%-10s %10s %10s\n", "Name", "Sales", "Percent"
         print "================================"
       } 
       {
         sum += $2
         name[NR] = $1
         sales[NR] = $2
       } 
       END {
         for(i=1; i<=NR; i++) {
           printf "%-10s %10d %9.1f%%\n", name[i], sales[i], (sales[i]/sum)*100
         }
       }' sales_data.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

🎮 理解度チェック

Q3: awk '{sum += $2} END {print sum}'はENDブロックで何をしますか?

awk '{sum += $2} END {print sum}'はENDブロックで何をしますか?

さらに高度な機能

配列でデータを管理

awkの配列はとても便利で、特に連想配列(ハッシュ)が強力です:

# 部署別の売上集計
$ awk '{dept[$3] += $2} END {for (d in dept) print d ":", dept[d]}' employee.txt

# 月別・商品別の売上(多次元配列)
$ awk '{sales[$1,$2] += $3} END {for (key in sales) print key ":", sales[key]}' monthly_sales.txt

関数も使える!

組み込み関数や、自分で関数を定義することもできます:

# 絶対値を求める関数を定義
$ awk 'function abs(x) {return x<0 ? -x : x} {print $1, abs($2)}' data.txt

# 平方根や対数などの数学関数
$ awk '{print $1, sqrt($2), log($2)}' numbers.txt

文字列操作も得意!

文字列の加工も簡単にできます:

# 文字列の長さを調べる
$ awk '{print $1, length($1)}' words.txt

# 最初の3文字だけ取り出す
$ awk '{print substr($1, 1, 3)}' names.txt

# 大文字・小文字に変換
$ awk '{print toupper($1), tolower($2)}' data.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

よく使う便利なワンライナー

システム管理でよく使う

これらはそのままコピーして使える便利なコマンドです:

# メモリをたくさん使っているプロセスTOP10
$ ps aux | awk 'NR>1 {print $2, $4, $11}' | sort -k2 -nr | head -10

# ディスク容量が80%を超えたパーティションを警告
$ df -h | awk 'NR>1 && $5+0 > 80 {print "警告:", $1, $5}'

$5+0は「%」を取り除いて数値に変換するテクニックです。「95%」→「95」になります!

ログファイルの分析

エラーの集計や時間帯別の分析もお手の物:

# エラーレベル別にカウント
$ awk '/ERROR/ {err++} 
       /WARN/ {warn++} 
       /INFO/ {info++} 
       END {print "Errors:", err, "Warnings:", warn, "Info:", info}' app.log

# 何時にアクセスが多いか分析
$ awk '{split($4, time, ":"); hour = substr(time[1], 2); count[hour]++} 
       END {for (h in count) print h ":00", count[h]}' access.log

データ形式の変換

ファイル形式の変換も簡単です:

# JSON形式に変換
$ awk '{printf "{\"name\": \"%s\", \"value\": %d},\n", $1, $2}' data.txt

# タブ区切り→カンマ区切りに変換
$ awk 'BEGIN {OFS=","} {$1=$1; print}' data.tsv

大きなファイルでも高速に処理

パフォーマンスを意識した書き方

巨大なファイルを扱う時のコツです:

# 見つかったらすぐ終了(無駄な処理をしない)
$ awk '/pattern/ {print; exit}' largefile.txt

# 100行目から200行目だけ処理
$ awk 'NR >= 100 && NR <= 200 {print $2}' file.txt

リアルタイム処理も可能

ログをリアルタイムで監視することもできます:

# 大きなファイルでも高速に行数カウント
$ awk '{count++} END {print count}' bigfile.txt

# リアルタイムでエラーを監視
$ tail -f log.txt | awk '/ERROR/ {print strftime("%Y-%m-%d %H:%M:%S"), $0}'

複雑な処理はスクリプトファイルに

「コマンドが長くなりすぎた!」そんな時は、スクリプトファイルに書きましょう:

#!/usr/bin/awk -f
# report.awk - 売上レポート生成スクリプト

BEGIN {
    FS = ","              # 入力はCSV
    OFS = "\t"            # 出力はタブ区切り
    print "売上レポート"
    print "============"
}

NR > 1 {  # ヘッダーをスキップ
    total += $3
    count++
    if ($3 > max) {
        max = $3
        max_product = $1
    }
}

END {
    print "総売上:", total
    print "平均:", total/count
    print "ベストセラー:", max_product, "(" max "円)"
}

実行方法はこちら:

$ awk -f report.awk sales.csv
# または実行権限を付けて
$ chmod +x report.awk
$ ./report.awk sales.csv

よくあるトラブルと解決法

フィールド番号を間違えた!

「あれ?何も表示されない...」そんな時の対処法:

# 存在しないフィールドを指定してもエラーにならない(空文字列)
$ awk '{print $10}' three_column_file.txt

# フィールド数をチェックしてから出力
$ awk 'NF >= 10 {print $10}' file.txt

数値と文字列が混ざってる!

「100」と「100円」が混在しているようなデータでも大丈夫:

# +0を付けると強制的に数値に変換
$ awk '{sum += $2+0} END {print sum}' mixed_data.txt

+0は魔法の呪文!文字列を数値に変換してくれます。「100円」→「100」になります。

📝 まとめ

今回はawkコマンドについて学びました!

  • awkはテキストデータを列単位で処理できる強力なツール
  • $1、1列目、$2、2列目...$0は行全体
  • -FオプションでCSVなど様々な区切り文字に対応
  • 条件処理、計算、集計が簡単にできる
  • BEGIN/ENDブロックでヘッダーや集計結果を出力

awkは最初は難しく感じるかもしれませんが、{print $2}のようなシンプルな列抽出から始めて、徐々に機能を増やしていけば、すぐに使いこなせるようになります。

Excelを開かずにコマンド一つでデータ処理ができるawkは、データ分析やログ解析の強い味方です。ぜひマスターして、日々の作業を効率化しましょう!

これで、grepで検索、sedで編集、awkで分析というテキスト処理の三大ツールをすべて学びました。この3つを組み合わせれば、どんなテキストデータでも怖くありません!

YouTube動画で復習

動画でさらに詳しく学びたい方は、CommandAcademyのYouTubeチャンネルをチェック!視覚的にコマンドの動作を確認できます。

awkをマスターするコツは「実際のデータで練習する」こと。自分の仕事で使うCSVファイルやログファイルで試してみましょう!