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

awkのgetlineを理解するための実践ガイドと安全な使い方

updated: 2026/05/05 created: 2026/04/29

はじめに

テキスト処理の世界に足を踏み入れると、必ずと言っていいほど出会う強力なツールがawkです。一行ずつデータを読み込み、パターンに一致する行を処理するというシンプルな基本ループは非常に強力ですが、複雑な集計や外部データの参照が必要になると、その「自動的な一行読み込み」がもどかしく感じることがあります。そこで登場するのがgetlineです。

本記事では、初学者が直面しやすい壁を一つずつ取り除きながら、この関数の使い方を解説します。標準的なループの流れをあえて制御し、自由自在にデータを引き出すテクニックを身につければ、あなたのスクリプトの柔軟性は飛躍的に向上するはずです。

参考:GNU awk

awkの基本ループとgetlineによる介入のメカニズム

ファイル作成

cat << 'EOF' > input.txt line1 line2 line3 EOF

実行コマンド

awk '{ print $0 }' input.txt

実行結果

line1
line2
line3

実行コマンド

awk '{ print "現在行:", $0 if (getline next_line) { print "getline取得:", next_line } }' input.txt

実行結果

現在行: line1
getline取得: line2
現在行: line3

仕組み

項目内容
通常ループawkは1行ずつ自動で読み込み処理する
getline次の行を明示的に取得し、処理の流れに介入する
行の進み方getlineを使うと内部ポインタが進むため、通常ループに影響する
変数格納getlineで取得した行は指定変数(例: next_line)に入る

解説

getlineは「自動ループに割り込んで次の行を先読みする仕組み」です。
そのため、使い方次第で行スキップや複雑な制御が可能になります。

getlineの戻り値(1, 0, -1)に基づくエラーハンドリングと終了判定

ファイル作成

cat << 'EOF' > input.txt line1 line2 EOF

実行コマンド

awk '{ while ((ret = getline line) >= 0) { if (ret == 1) { print "OK:", line } else if (ret == 0) { print "EOF reached" break } else if (ret == -1) { print "Error occurred" } } }' input.txt

実行結果

OK: line2
EOF reached

仕組み

戻り値意味動作内容
1正常に1行読み込んだ読み込んだ内容を処理
0EOF(ファイル終端)ループ終了の判定に使用
-1エラー発生エラーハンドリングを実行

解説

awk getlineは戻り値で状態を判定できるため、明示的にEOFやエラー処理を書けます。
特にバッチ処理では-1の検出を入れておくと堅牢性が上がります。

外部ファイルからのデータ読み込み

ファイル作成

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

実行コマンド

awk '{ getline line < "input.txt"; print "read:", line }' input.txt

実行結果

read: apple 100
read: banana 200
read: orange 300

仕組み

要素説明
awkテキスト処理ツール
getline line < "input.txt"外部ファイルから1行読み込み、変数lineに格納
< "input.txt"標準入力とは別のファイルを指定
print読み込んだ内容を出力
繰り返しawkの各行処理ごとにgetlineが実行される

解説

getlineを使うことで、現在処理中の入力とは別に外部ファイルからデータを読み込めます。
ファイルを順次読み進めるため、ループごとに1行ずつ取得されます。

変数への格納による$0(カレントレコード)の保護と使い分け

ファイル作成

cat << 'EOF' > input.txt A 100 B 200 C 300 EOF

実行コマンド

awk '{ line = $0 if ((getline next_line) <= 0) { next_line = "" } print "current:", line, "| next:", next_line }' input.txt

実行結果

current: A 100 | next: B 200
current: C 300 | next: 

仕組み

要素内容
$0現在処理中の行(カレントレコード)
line = $0$0を変数に退避(保護)
getline次の行を読み込み、$0を上書き
next_linegetlineで取得した次の行を保持
問題点getlineすると元の$0が消える
解決策事前に変数へ保存して使い分け

解説

getlineは$0を上書きするため、そのままだと元の行が失われる。
事前に変数へ退避することで、現在行と次行を安全に扱える。

パイプ経由でのコマンド実行結果の取得

ファイル作成

cat << 'EOF' > input.txt apple banana cherry EOF

実行コマンド

echo "dummy" | awk '{ "cat input.txt" | getline line; print line }'

実行結果

apple

実行コマンド

echo "dummy" | awk '{ "cat input.txt" | getline line; print line; "cat input.txt" | getline line; print line }'

実行結果

apple
banana

仕組み

要素内容
"cat input.txt" | getline line外部コマンドを実行し、その出力を1行取得
getlineパイプから1行ずつ読み込む
line読み込んだ内容を格納する変数
print line取得した行を出力
繰り返しgetline次の行を順次取得可能

解説

awkのgetlineは外部コマンドの出力を直接取り込めるため、パイプ経由のデータ処理に柔軟性を持たせられます。
複数回呼び出すことで、ストリームを順次読み進めることができます。
また、echo dummyはawkを1回起動するためのトリガーとして機能します。

BEGINブロックにおける初期設定ファイルの先読みテクニック

ファイル作成

cat << 'EOF' > config.txt name=John age=30 EOF

ファイル作成

cat << 'EOF' > input.txt data1 data2 EOF

実行コマンド

awk 'BEGIN { while ((getline line < "config.txt") > 0) { split(line, a, "=") conf[a[1]] = a[2] } } { print $0, conf["name"], conf["age"] }' input.txt

実行結果

data1 John 30
data2 John 30

仕組み

フェーズ処理内容awk getlineの役割
BEGINconfig.txtを1行ずつ読む入力本体とは別ファイルを先読み
BEGINsplitでキーと値に分割設定値を配列へ格納
メイン処理input.txtを1行ずつ処理事前に読み込んだ設定を利用
出力データ+設定値を表示conf配列を参照

解説

BEGIN内でgetlineを使うことで、メイン入力処理前に設定ファイルを読み込める。
これにより、擬似的な初期設定ファイルの仕組みをawk単体で実現できる。

複数ファイル操作時の必須処理

ファイル作成

cat << 'EOF' > input.txt A 1 B 2 C 3 EOF

ファイル作成

cat << 'EOF' > ref.txt A Apple B Banana C Cherry EOF

実行コマンド

awk 'NR==FNR { map[$1]=$2; next } { print $0, map[$1] }' ref.txt input.txt

実行結果

A 1 Apple
B 2 Banana
C 3 Cherry

実行コマンド

awk '{ getline line < "ref.txt"; split(line, a, " "); print $0, a[2] }' input.txt

実行結果

A 1 Apple
B 2 Banana
C 3 Cherry

仕組み

要素内容
NR==FNR最初のファイル(ref.txt)読み込み時のみ処理
map配列キー($1)に対応する値($2)を保持
getline別ファイルから1行ずつ読み込む
split読み込んだ行を配列に分割
next次のレコードへスキップ

解説

awk getline を使うことで別ファイルを逐次読み込みでき、複数ファイルを同時に扱う処理が可能になります。
ただし、対応関係がある場合は配列で事前に読み込む方法のほうが安全で一般的です。

getline を使うべき場面とnextで十分な場面

ファイル作成

cat << 'EOF' > input.txt A 1 B 2 C 3 EOF

実行コマンド

awk '{ print $0; if(getline > 0) { print "next line:", $0 } else { print "next line:" } }' input.txt

実行結果

A 1
next line: B 2
C 3
next line: 

実行コマンド

awk '{ print $0; next }' input.txt

実行結果

A 1
B 2
C 3

仕組み

機能動作内容レコード消費主な用途
getline次の行を明示的に読み込み、$0を上書きする先読み・複数行処理
next現在行の処理を終了し次のレコードへ進むする単純なスキップ・高速処理

解説

getline は「次の行を自分で取りにいく」制御が必要な場面で使う。
next は「今の処理を打ち切るだけ」で十分なシンプルなケースに向いている。

無限ループを防ぐための条件式の書き方

ファイル作成

cat << 'EOF' > input.txt line1 line2 line3 EOF

実行コマンド

awk '{ count=0 while ((getline next_line) > 0) { print $0 " -> " next_line count++ if (count > 2) break } }' input.txt

実行結果

line1 -> line2
line1 -> line3

仕組み

要素内容
getline次の行を読み込んで変数に格納する
while ((getline) > 0)EOFまでループする条件
count変数ループ回数を制御する
break一定回数で強制終了し無限ループ防止
$0現在行の内容
next_linegetlineで取得した次の行

解説

awk getlineは条件なしだとEOFまで読み続けるため無限ループになりやすいです。
回数制御やbreakを組み合わせるのが安全です。

複数ファイルの特定列を結合・比較するデータ処理

ファイル作成

cat << 'EOF' > file1.txt A 100 B 200 C 300 EOF

ファイル作成

cat << 'EOF' > file2.txt A apple B banana D durian EOF

実行コマンド

awk 'NR==FNR { data[$1]=$2; next } { if ($1 in data) print $1, data[$1], $2; else print $1, "N/A", $2 }' file1.txt file2.txt

実行結果

A 100 apple
B 200 banana
D N/A durian

実行コマンド

awk '{ while ((getline line < "file1.txt") > 0) { split(line, a, " ") if ($1 == a[1]) { print $1, a[2], $2 found=1 break } } close("file1.txt") if (!found) print $1, "N/A", $2 found=0 }' file2.txt

実行結果

A 100 apple
B 200 banana
D N/A durian

仕組み

処理ステップ内容
ファイル読込11つ目のファイル(file1.txt)を連想配列に格納
キー抽出1列目をキーとして扱う
照合処理2つ目のファイル(file2.txt)とキー一致を確認
結合処理一致時は値を結合、不一致はN/A
getline版file2.txt処理中にfile1.txtを逐次読み込み比較

解説

NR==FNRを使う方法は高速で一般的、getlineは逐次比較の仕組み理解に向いています。
どちらも特定列をキーにした結合処理の基本パターンです。

awkとgetlineを駆使した効率的なデータ制御

awkの基本ループというレールから一歩踏み出し、getlineによる能動的なデータ制御を学ぶことは、初学者が中級者へとステップアップするための大きな関門です。$0の保護や戻り値のチェック、そして適切なclose処理。これらは一見細かいルールに見えますが、大規模なデータを正確に、かつ高速に処理するためには欠かせない知識です。

自動化されたループの利便性を享受しつつ、ここぞという場面でgetlineを介入させる。このバランス感覚を磨くことで、あなたのコマンドラインでの作業効率は劇的に向上することでしょう。今回紹介したテクニックを、ぜひ日々のログ解析やレポート作成に役立ててみてください。

コメントを残す

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

©︎ 2025-2026 running terminal commands