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

awkのmatch関数を使いこなす実践ガイド

updated: 2026/05/05 created: 2026/04/30

はじめに

awkはテキスト処理に特化した強力なツールですが、初学者がつまずきやすいポイントのひとつがmatch関数と正規表現の扱いです。特に、単純な検索だけでなく「どこにマッチしたのか」「どれくらいの長さなのか」といった情報を扱う場面では、理解が曖昧なままだと応用が効きません。

本記事では、組み込み変数RSTARTとRLENGTHの仕組みから、~演算子との違い、ループ処理への応用、日本語処理やパフォーマンス改善まで、実務で役立つ形で整理します。読み進めることで、単なる文字列検索から一歩進んだ実践的なテキスト処理ができるようになることを目指します。

参考元: GNU awk

組み込み変数RSTARTとRLENGTHの役割と仕組み

ファイル作成

cat << 'EOF' > input.txt Hello 123 World abc456def no numbers here EOF

実行コマンド

awk '{ if (match($0, /[0-9]+/)) print $0, "-> RSTART=" RSTART ", RLENGTH=" RLENGTH }' input.txt

実行結果

Hello 123 World -> RSTART=7, RLENGTH=3
abc456def -> RSTART=4, RLENGTH=3

仕組み

項目内容
match関数文字列から正規表現に一致する位置を検索
RSTARTマッチした開始位置(1始まり)
RLENGTHマッチした文字列の長さ
マッチなしRSTART=0、RLENGTH=-1
更新タイミングmatch実行時に自動更新

解説

match関数は一致位置と長さを内部変数に格納し、後続処理で再利用できる点が重要です。
これにより、部分文字列の抽出や位置ベースの処理が簡潔に書けます。

matchと~演算子(正規表現マッチ)の決定的な違いと使い分け

ファイル作成

cat << 'EOF' > input.txt apple 123 banana abc cherry 456def date 789 EOF

実行コマンド

awk '{ if (match($0, /[0-9]+/)) print $0, "-> match at", RSTART, "length", RLENGTH }' input.txt

実行結果

apple 123 -> match at 7 length 3
cherry 456def -> match at 8 length 3
date 789 -> match at 6 length 3

実行コマンド

awk '{ if ($0 ~ /[0-9]+/) print $0 }' input.txt

実行結果

apple 123
cherry 456def
date 789

仕組み

項目match 関数~ 演算子
役割正規表現の位置・長さを取得正規表現にマッチするか判定
戻り値マッチ位置(0なら不一致)真(1)/偽(0)
追加情報RSTART, RLENGTH が使えるなし
用途位置や部分文字列の解析単純な条件分岐
柔軟性高いシンプル

解説

match は「どこにマッチしたか」まで扱える解析向き、~は「マッチするかだけ」を見る条件分岐向きです。
用途で使い分けるのが基本です。

正規表現のメタ文字を利用した高度なパターンマッチング手法

ファイル作成

cat << 'EOF' > input.txt apple 123 banana 456 cherry abc date 789xyz EOF

実行コマンド

awk 'match($0, /[a-z]+ [0-9]+/) { print "MATCH:", $0 }' input.txt

実行結果

MATCH: apple 123
MATCH: banana 456
MATCH: date 789xyz

実行コマンド

awk 'match($0, /[0-9]+$/) { print "END NUMBER:", $0 }' input.txt

実行結果

END NUMBER: apple 123
END NUMBER: banana 456

実行コマンド

awk 'match($0, /^[a-z]+ [0-9]+$/) { print "STRICT MATCH:", $0 }' input.txt

実行結果

STRICT MATCH: apple 123
STRICT MATCH: banana 456

仕組み

要素説明
match()文字列が正規表現に一致するか判定する関数
[a-z]+小文字アルファベットが1回以上続く
[0-9]+数字が1回以上続く
^行の先頭を示す
$行の末尾を示す
$0行全体を表すawkの変数
/pattern/正規表現リテラル

解説

match()を使うことで、行単位で高度な正規表現マッチングが可能になります。
アンカー(^, $)や量指定子(+)を組み合わせることで、厳密な条件指定ができます。

match関数をループ処理(while)で活用する方法

ファイル作成

cat << 'EOF' > input.txt abc123def456ghi789 EOF

実行コマンド

awk '{ while (match($0, /[0-9]+/)) { print substr($0, RSTART, RLENGTH) $0 = substr($0, RSTART + RLENGTH) } }' input.txt

実行結果

123
456
789

仕組み

要素内容
match関数正規表現に一致した位置を返す
RSTART一致開始位置
RLENGTH一致した長さ
substr一致部分の抽出
whileループ一致がなくなるまで繰り返し
$0の更新次の検索のため文字列を切り詰め

解説

matchで数値部分を検出し、whileで繰り返すことで全て抽出しています。
$0を書き換えることで、前回の一致以降を対象にしているのがポイントです。

ログファイルから特定のタイムスタンプやIDのみを抜き出す

ファイル作成

cat << 'EOF' > input.txt 2026-04-29 10:15:23 ID:1001 INFO Login success 2026-04-29 10:16:10 ID:1002 ERROR Failed attempt 2026-04-29 10:17:45 ID:1003 INFO Logout 2026-04-29 10:18:00 ID:1002 INFO Login success EOF

実行コマンド

awk 'match($0, /ID:1002/)' input.txt

実行結果

2026-04-29 10:16:10 ID:1002 ERROR Failed attempt
2026-04-29 10:18:00 ID:1002 INFO Login success

実行コマンド

awk 'match($0, /^2026-04-29 10:17/)' input.txt

実行結果

2026-04-29 10:17:45 ID:1003 INFO Logout

仕組み

要素内容
awkテキストを1行ずつ処理するコマンド
match()正規表現に一致するか判定
$0行全体を表す
/ID:1002/特定IDに一致
/^2026-04-29 10:17/指定時刻で始まる行に一致

解説

match()を使うことで、正規表現に一致した行だけを柔軟に抽出できます。
IDやタイムスタンプなど複雑な条件にも対応可能です。

マルチバイト文字(日本語)を扱う際のmatch関数の注意点と設定

ファイル作成

cat << 'EOF' > input.txt こんにちは123 abc日本語456 EOF

実行コマンド

awk '{ if (match($0, /[0-9]+/)) print substr($0, RSTART, RLENGTH) }' input.txt

実行結果

123
456

実行コマンド

export LC_ALL=ja_JP.UTF-8 awk '{ if (match($0, /日本語/)) print substr($0, RSTART, RLENGTH) }' input.txt

実行結果

日本語

仕組み

項目内容
match関数正規表現に一致した位置をRSTARTに、長さをRLENGTHに格納
RSTARTマッチ開始位置(1始まり)
RLENGTHマッチした文字数
substrRSTARTとRLENGTHを使って一致部分を取得
問題点デフォルト環境ではマルチバイト文字を1文字として扱わない場合がある
対策LC_ALL=UTF-8 などロケールをUTF-8に設定

解説

awkのmatchはロケールに依存するため、日本語を扱う場合はUTF-8環境を明示する必要があります。
設定しないと文字位置や長さが正しく取得できないことがあります。

大量のデータを処理する際のmatchの処理速度向上策

ファイル作成

seq -f "%.0f" 5000000 | sed 's/^/apple_/' > input.txt

実行コマンド

time awk '{ if (match($0, /apple_[0-9]+/)) print }' input.txt

実行結果

real	0m17.488s
user	0m8.886s
sys	0m3.553s

実行コマンド

time awk 'BEGIN { pattern = "apple_[0-9]+" } { if ($0 ~ pattern) print }' input.txt

実行結果

real	0m16.747s
user	0m8.320s
sys	0m3.529s

実行コマンド

time awk '{ if (index($0, "apple_")) print }' input.txt

実行結果

real	0m16.200s
user	0m7.591s
sys	0m3.467s

仕組み

手法内容速度特徴
match関数毎回正規表現を評価遅い柔軟だがコスト高
正規表現変数化パターンを事前定義して再利用コンパイル回数削減
index関数文字列検索のみ速い単純一致に最適

解説

大量データでは正規表現の再評価コストが支配的になるため、変数化や単純関数への置き換えが有効です。
特に条件が単純ならindexが最速です。

「マッチしない場合」の戻り値のハンドリング

ファイル作成

cat << 'EOF' > input.txt apple 100 banana 200 cherry 300 EOF

実行コマンド

awk '{ result = match($0, /orange/); print result }' input.txt

実行結果

0
0
0

実行コマンド

awk '{ result = match($0, /apple/); print result }' input.txt

実行結果

1
0
0

仕組み

条件match関数の戻り値意味
マッチする1以上の数値マッチした開始位置
マッチしない0一致しなかった
resultに格納数値条件分岐に利用可能

解説

matchは一致しない場合に0を返すため、その値で分岐処理を書くことで安全にハンドリングできます。

awkとmatchを使いこなすためのまとめ

awkにおけるmatchの理解は、単なる正規表現の知識ではなく「処理の流れ」を掴むことが重要です。

細かな仕様を理解することで一気に応用範囲が広がります。

今回紹介したポイントを押さえることで、初学者の段階から実務レベルのテキスト処理に近づくことができます。

コメントを残す

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

©︎ 2025-2026 running terminal commands