クリップボードにコピーしました!
文字列のawk

awkのfunctionを理解して効率的なテキスト処理を実現するための実践ガイド

updated: 2026/05/05 created: 2026/04/23

はじめに

awkはテキスト処理に特化した強力なツールですが、ある程度使い慣れてくると処理が複雑になり、可読性や保守性の低下に悩む場面が増えてきます。

そこで重要になるのがfunctionの活用です。関数を使うことで処理を整理し、再利用性を高めることができます。

本記事では、初学者がつまずきやすいポイントに触れながら、実践的に理解できるよう解説していきます。

参考: GNU gawk

ユーザー定義関数の基本構文と定義場所

ファイル作成

cat << 'EOF' > input.txt apple 100 banana 200 orange 150 EOF

実行コマンド

awk ' function add_tax(price) { return price * 1.1 } { taxed = add_tax($2) print $1, taxed } ' input.txt

実行結果

apple 110
banana 220
orange 165

仕組み

要素内容
function add_tax(price)ユーザー定義関数の宣言
return price * 1.1関数の戻り値(10%加算)
$22列目(価格)を取得
taxed = add_tax($2)関数を呼び出して計算
print $1, taxed商品名と計算結果を出力
定義場所awkスクリプト内の先頭または任意位置(処理前に解釈される)

解説

awkでは function を使って独自の処理をまとめられます。
関数はスクリプト内のどこに書いても、実行前に読み込まれるため柔軟に配置できます。

組み込み関数とユーザー定義関数の使い分け

ファイル作成

cat << 'EOF' > input.txt 10 20 30 40 EOF

実行コマンド

awk '{print $1 + $2}' input.txt

実行結果

30
70

実行コマンド

awk ' function add(a, b) { return a + b } { print add($1, $2) } ' input.txt

実行結果

30
70

仕組み

種類記述方法特徴使用例
組み込み関数そのまま使用簡潔で高速$1 + $2
ユーザー定義関数function 関数名()再利用・可読性向上add(a, b)

解説

組み込み関数はシンプルな処理に適しており、短く書けます。
複雑な処理や再利用が必要な場合はユーザー定義関数を使うのが効果的です。

戻り値の適切な活用と条件分岐による早期リターン

ファイル作成

cat << 'EOF' > input.txt function is_valid(n) { if (n < 0) return 0 if (n == 0) return 1 return 2 } { result = is_valid($1) <code>if (result == 0) { print "negative" next } if (result == 1) { print "zero" next } print "positive"</code> } EOF

実行コマンド

echo -e "-1\n0\n5" | awk -f input.txt

実行結果

negative
zero
positive

仕組み

要素内容
function is_valid(n)数値の状態を判定する関数
return 0負の値 → 即終了(早期リターン)
return 10 → 即終了
return 2正の値
result変数戻り値を受け取り条件分岐に利用
next条件成立時に後続処理をスキップ

解説

戻り値を使うことで条件判定を関数に集約し、分岐処理がシンプルになる。
早期リターンにより無駄な処理を避け、可読性と効率が向上する。

思わぬバグを防ぐスペース区切りのテクニック

ファイル作成

cat << 'EOF' > input.txt apple 10 banana 20 orange 30 EOF

実行コマンド

awk '{ total += $2 } END { print total }' input.txt

実行結果

60

実行コマンド

awk 'function add(x, y){ return x + y } { total = add(total, $2) } END { print total }' input.txt

実行結果

60

実行コマンド

awk '{ total += $2 } END { print "total =", total }' input.txt

実行結果

total = 60

仕組み

要素内容
$2スペース区切りで2番目のフィールド(数値)を取得
total += $2値を累積(スペース区切り前提)
function add(x, y)awk内で関数定義し安全に加算
END {}全行処理後に結果を出力
スペース区切りデフォルト区切りのためバグを防ぎやすい

解説

awkはデフォルトでスペース区切りのため、余計な区切り指定を省くことでバグを防げます。
関数化することで処理の意図が明確になり、保守性も向上します。

関数の引数における「値渡し」と「参照渡し(配列)」の挙動の違い

ファイル作成

cat << 'EOF' > input.txt function test_val(x) { x = 100 } function test_ref(arr) { arr[1] = 100 } BEGIN { a = 1 test_val(a) print "値渡し:", a <code>b[1] = 1 test_ref(b) print "参照渡し(配列):", b[1]</code> } EOF

実行コマンド

awk -f input.txt

実行結果

値渡し: 1
参照渡し(配列): 100

仕組み

項目渡し方関数内の変更呼び出し元への影響理由
スカラー変数値渡し変更される影響なしコピーが渡される
配列参照渡し変更される影響あり実体への参照が渡される

解説

awkの関数ではスカラーは値渡し、配列は参照渡しとして扱われます。
そのため配列は関数内の変更が呼び出し元に反映されます。

関数内でのprint|printfを活用した変数のトレース方法

ファイル作成

cat << 'EOF' > input.txt apple 100 banana 200 orange 150 EOF

実行コマンド

awk ' function debug_sum(x, y) { printf("DEBUG: x=%d, y=%d, sum=%d\n", x, y, x+y) return x + y } { total = debug_sum($2, 10) print $1, total } ' input.txt

実行結果

DEBUG: x=100, y=10, sum=110
apple 110
DEBUG: x=200, y=10, sum=210
banana 210
DEBUG: x=150, y=10, sum=160
orange 160

仕組み

要素内容
function debug_sumawkの関数定義
printf関数内で変数の状態をトレース出力
$22列目(数値)を取得
total関数の戻り値を格納
print最終結果の出力
DEBUG出力処理途中の値を確認するためのログ

解説

awkの関数内でprintfを使うことで、処理途中の変数を簡単にトレースできます。
デバッグ用途として非常に有効です。

fオプションを用いた外部ファイルからの読み込み管理

ファイル作成

cat << 'EOF' > data.txt apple 100 banana 200 orange 150 EOF

ファイル作成

cat << 'EOF' > script.awk function format(name, price) { return name ": " price " yen" } { print format($1, $2) } EOF

実行コマンド

awk -f script.awk data.txt

実行結果

apple: 100 yen
banana: 200 yen
orange: 150 yen

仕組み

要素内容
-f オプション外部ファイル(script.awk)を読み込む
functionawk内で独自関数を定義
$1, $2入力ファイルの1列目・2列目を参照
print加工した結果を出力

解説

-fを使うことでawkスクリプトを外部ファイルとして管理でき、可読性と再利用性が向上します。
function を使うと処理を分離でき、複雑なロジックでも整理しやすくなります。

複雑な正規表現処理や数値計算のモジュール化

ファイル作成

cat << 'EOF' > input.txt 10 apple 25 banana 5 orange 30 apple 15 banana EOF

ファイル作成

cat << 'EOF' > script.awk # 数値計算+正規表現+関数化 function add_sum(key, value) { sum[key] += value } { # 正規表現で英字のみ抽出 if (match($2, /^[a-zA-Z]+$/)) { add_sum($2, $1) } } END { for (k in sum) { printf "%s: %d\n", k, sum[k] } } EOF

実行コマンド

awk -f script.awk input.txt

実行結果

apple: 40
banana: 40
orange: 5

仕組み

要素内容
function add_sumキーごとの合計値を加算する関数
match正規表現で英単語のみを対象にする
sum配列連想配列でカテゴリごとに集計
ENDブロック最終結果を出力

解説

awkの関数を使うことで、数値集計ロジックを再利用可能に分離できます。
正規表現と組み合わせることで、柔軟なデータ処理が可能になります。

ディレクトリ構造や階層データの処理

ファイル作成

cat << 'EOF' > input.txt root/child1/grandchild1 root/child1/grandchild2 root/child2/grandchild3 EOF

実行コマンド

awk -F'/' '{ for(i=1;i<=NF;i++){ printf("level%d: %s ", i, $i) } print "" }' input.txt

実行結果

level1: root level2: child1 level3: grandchild1 
level1: root level2: child1 level3: grandchild2 
level1: root level2: child2 level3: grandchild3 

実行コマンド

awk -F'/' ' function show_tree(arr, n, i, indent){ indent="" for(i=1;i<=n;i++){ print indent arr[i] indent=indent " " } print "" } { split($0, parts, "/") show_tree(parts, length(parts)) } ' input.txt

実行結果

root
  child1
    grandchild1

root
  child1
    grandchild2

root
  child2
    grandchild3

仕組み

要素内容
-F'/'区切り文字を / に設定
split()文字列を配列に分解して階層構造化
function show_tree再利用可能な処理として階層表示を定義
indentインデントを増やしてツリー構造を表現
NF / length()フィールド数(階層の深さ)を取得

解説

awkのfunctionを使うことで、階層データを再利用可能なロジックとして扱える。
配列とインデント制御を組み合わせるとツリー構造の可視化が簡潔に実現できる。

関数呼び出しのオーバーヘッドとメインループの設計

ファイル作成

seq 10000000 > input.txt

実行コマンド

time awk ' function square(x) { return x * x } { print square($1) } ' input.txt

実行結果

real	0m41.943s
user	0m20.291s
sys	0m6.955s

実行コマンド

time awk ' { print $1 * $1 } ' input.txt

実行結果

real	0m37.662s
user	0m18.461s
sys	0m6.908s

仕組み

項目関数あり関数なし
処理場所function内メインループ
呼び出しコスト発生する発生しない
可読性高いやや低い
実行速度わずかに遅いわずかに速い
拡張性高い低い

解説

awkのfunctionは可読性と再利用性を高める一方、ループ内で多用すると関数呼び出しのオーバーヘッドが発生します。
高速性重視ならメインループに直接書く設計が有利です。

awkのfunctionを使いこなして保守性と可読性を高めるためのまとめ

awkにおけるfunctionの活用は、単なるテクニックではなく、コード全体の品質を左右する重要な要素です。
ユーザー定義関数を適切に設計し、組み込み関数と使い分けることで、無駄のない効率的な処理が実現できます。
また、値渡しと参照渡しの違いやスペース区切りの仕様など、細かな挙動を理解することがバグの防止につながります。
さらに、外部ファイルの活用やモジュール化によって、規模の大きな処理でも整理された構造を保つことができます。

関数の使い方を意識することで、awkは単なるワンライナーのツールから、実用的なスクリプト言語へと進化します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

©︎ 2025-2026 running terminal commands