はじめに
テキスト処理の現場でよく使われるコマンドのひとつにawkがあります。
特にログ解析やCSV処理など、行単位でデータを扱う場面では強力な武器になります。
その中でも重要な役割を持つのがnrという変数です。これは単なる行番号に見えますが、使いこなすことで抽出・集計・フィルタリングといった処理をシンプルに記述できるようになります。
本記事ではawkの基本構造から始まり、nrの役割やfnrとの違い、具体的なデータ抽出テクニックまでを体系的に解説します。
初学者がつまずきやすいポイントにも触れながら、役立つ使い方を理解できるよう構成しています。
参考:GNU awk
AWKの基本構造とNR変数の役割
ファイル作成
cat << 'EOF' > input.txt
apple
banana
cherry
EOF
実行コマンド
awk '{print NR, $0}' input.txt
実行結果
1 apple
2 banana
3 cherry
実行コマンド
awk 'NR==2 {print $0}' input.txt
実行結果
banana
仕組み
| 要素 | 内容 |
|---|---|
| awk | テキスト処理ツール(行単位で処理) |
| NR | 現在処理している行番号(1から始まる) |
| $0 | 行全体の内容 |
| NR==2 | 「2行目のみ処理する」という条件指定 |
解説
NRは行番号を自動でカウントする変数で、行ごとの条件分岐や番号付き出力に使われます。
awkの基本は「1行ずつ読み込んで条件と処理を適用する」ことです。
NR(レコード番号)とFNR(ファイルごとの行番号)の違い
ファイル作成
cat << 'EOF' > input1.txt
A
B
C
EOF
ファイル作成
cat << 'EOF' > input2.txt
D
E
EOF
実行コマンド
awk '{print NR, FNR, $0}' input1.txt input2.txt
実行結果
1 1 A
2 2 B
3 3 C
4 1 D
5 2 E
仕組み
| 項目 | NR | FNR |
|---|---|---|
| 意味 | 全ファイル通算の行番号 | 各ファイルごとの行番号 |
| リセット | されない | ファイルごとにリセット |
| input1.txt | 1,2,3 | 1,2,3 |
| input2.txt | 4,5 | 1,2 |
解説
NRは全体の通し番号、FNRはファイル単位の番号です。
複数ファイル処理時の違いを把握するのがポイントです。
特定の行番号を指定してデータを抽出するテクニック
ファイル作成
cat << 'EOF' > input.txt
apple
banana
cherry
date
elderberry
fig
grape
EOF
実行コマンド
awk 'NR==3' input.txt
実行結果
cherry
実行コマンド
awk 'NR>=2 && NR<=4' input.txt
実行結果
banana
cherry
date
実行コマンド
awk 'NR%2==0' input.txt
実行結果
banana
date
fig
仕組み
| 要素 | 説明 |
|---|---|
| NR | 現在処理中の行番号(自動でカウントされる) |
| NR==3 | 3行目のみ出力 |
| NR>=2 && NR<=4 | 2〜4行目の範囲を抽出 |
| NR%2==0 | 偶数行のみ出力(行番号を2で割った余りが0) |
解説
awkのNRは行番号を扱う基本変数で、条件式と組み合わせるだけで柔軟な抽出が可能です。
シンプルながらログ解析やデータ処理でかなり強力に使えます。
NRを用いた「n行おき」のデータサンプリング方法
ファイル作成
cat << 'EOF' > input.txt
1 apple
2 banana
3 cherry
4 date
5 elderberry
6 fig
7 grape
8 honeydew
EOF
実行コマンド
awk 'NR % 3 == 0' input.txt
実行結果
3 cherry
6 fig
実行コマンド
awk 'NR % 3 == 1' input.txt
実行結果
1 apple
4 date
7 grape
仕組み
| 要素 | 内容 |
|---|---|
| NR | 現在の行番号(1からスタート) |
| NR % n | 行番号をnで割った余り |
| 条件一致 | 余りが特定値のとき行を出力 |
| 応用 | 開始位置を変えて柔軟にサンプリング可能 |
解説
NRは行番号を表し、剰余演算と組み合わせることで周期的な行抽出ができます。
ログ解析や間引き処理でよく使われるシンプルかつ強力な手法です。
演算子を組み合わせた特定範囲(行数)の切り出し処理
ファイル作成
cat << 'EOF' > input.txt
line1
line2
line3
line4
line5
line6
EOF
実行コマンド
awk 'NR>=2 && NR<=4' input.txt
実行結果
line2
line3
line4
実行コマンド
awk 'NR==3, NR==5' input.txt
実行結果
line3
line4
line5
仕組み
| 構文 | 意味 | 動作 |
|---|---|---|
| NR | 現在の行番号 | 1行目から順にカウントされる |
| NR>=2 && NR<=4 | 範囲条件(論理演算) | 2〜4行目のみ出力 |
| NR==3, NR==5 | 範囲指定(レンジ演算子) | 3行目から5行目まで連続出力 |
| && | AND条件 | 両方の条件を満たす行のみ対象 |
解説
awkのNRを使うと、論理演算やレンジ指定で柔軟に行範囲を抽出できます。
特にNR==A,NR==Bは開始〜終了まで自動的に出力されるので便利です。
NRとENDブロックを活用した最終行の特定とデータ統計
ファイル作成
cat << 'EOF' > input.txt
apple 10
banana 20
orange 15
grape 25
EOF
実行コマンド
awk '{ sum += $2 } END { print "最終行:", NR, "合計:", sum }' input.txt
実行結果
最終行: 4 合計: 70
実行コマンド
awk 'NR==1{min=$2; max=$2} { if($2max) max=$2 } END{ print "件数:", NR, "最小:", min, "最大:", max }' input.txt
実行結果
件数: 4 最小: 10 最大: 25
仕組み
| 要素 | 説明 |
|---|---|
| NR | 現在処理中の行番号(最終行では総行数になる) |
| $2 | 各行の2列目(数値データ) |
| sum += $2 | 数値の累積計算 |
| END | 全行処理後に1回だけ実行されるブロック |
| NR==1 | 初期値設定(最初の行で実行) |
| min / max | 最小値・最大値の更新用変数 |
解説
NRは行数カウンタとして機能し、ENDと組み合わせることで「最終行=総件数」を自然に取得できます。
統計処理も1パスで完結できるのがawkの強みです。
複数ファイル処理時におけるNRの挙動と注意点
ファイル作成
cat << 'EOF' > file1.txt
A1
A2
A3
EOF
ファイル作成
cat << 'EOF' > file2.txt
B1
B2
EOF
実行コマンド
awk '{print NR, $0}' file1.txt file2.txt
実行結果
1 A1
2 A2
3 A3
4 B1
5 B2
実行コマンド
awk '{print FNR, $0}' file1.txt file2.txt
実行結果
1 A1
2 A2
3 A3
1 B1
2 B2
実行コマンド
awk 'FNR==1{print "--- new file ---"} {print NR, FNR, $0}' file1.txt file2.txt
実行結果
--- new file ---
1 1 A1
2 2 A2
3 3 A3
--- new file ---
4 1 B1
5 2 B2
仕組み
| 項目 | 意味 | ファイル跨ぎ時の挙動 |
|---|---|---|
| NR | 全体の累計行番号 | リセットされない |
| FNR | ファイルごとの行番号 | ファイルごとにリセットされる |
| FNR==1 | 新しいファイルの先頭判定 | ファイル切替の検知に使える |
解説
NRは全入力を通した連番、FNRはファイル単位での連番なので、複数ファイル処理では用途に応じて使い分ける必要があります。
特にファイル境界の検知にはFNR==1が定番です。
NRを使用した簡易的なCSVヘッダーのスキップ処理
ファイル作成
cat << 'EOF' > input.txt
name,age,city
Alice,30,Tokyo
Bob,25,Osaka
Charlie,35,Nagoya
EOF
実行コマンド
awk 'NR>1' input.txt
実行結果
Alice,30,Tokyo
Bob,25,Osaka
Charlie,35,Nagoya
仕組み
| 要素 | 説明 |
|---|---|
| NR | 現在処理中の行番号(1から開始) |
| NR>1 | 1行目(ヘッダー)を除外し、2行目以降のみ処理 |
| awk | テキストを行単位で処理するコマンド |
| input.txt | 処理対象のCSVファイル |
解説
NRを使うことで行番号ベースの制御が可能になり、シンプルにヘッダーをスキップできます。
CSV処理の前処理として軽量でよく使われる方法です。
NRと他の組み込み変数(NF等)を組み合わせたフィルタリング
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
orange 150
grape 300
melon 250
EOF
実行コマンド
awk 'NR <= 3 {print NR, $0}' input.txt
実行結果
1 apple 100
2 banana 200
3 orange 150
実行コマンド
awk 'NF == 2 && $2 >= 200 {print NR, $1, $2}' input.txt
実行結果
2 banana 200
4 grape 300
5 melon 250
実行コマンド
awk 'NR % 2 == 1 && NF == 2 {print NR, $0}' input.txt
実行結果
1 apple 100
3 orange 150
5 melon 250
仕組み
| 要素 | 意味 | 役割 |
|---|---|---|
| NR | レコード番号(行番号) | 行ベースの条件指定 |
| NF | フィールド数 | 列数のチェック |
| $1, $2 | 各フィールド | データの抽出・比較 |
| 条件式 (NR <= 3 等) | フィルタ条件 | 抽出対象の制御 |
| 論理演算子 (&&, %) | 条件の組み合わせ | 複雑なフィルタリング |
解説
NRで行を制御しつつ、NFやフィールド値を組み合わせることで柔軟な抽出が可能です。
行番号・列数・値条件を同時に扱えるのがawkの強みです。
awkとnrを使いこなすための実践ポイントまとめ
awkにおけるnrは単なる行番号ではなく、条件分岐やデータ抽出の軸となる重要な要素です。
fnrとの違いを理解し、単一ファイルか複数ファイルかで適切に使い分けることが基本になります。
また、特定行の抽出、n行おきのサンプリング、範囲指定、最終行の取得など、nrを使った典型的なパターンを押さえておくことで、日常的なテキスト処理の多くを効率化できます。
さらにNFなどの他の変数と組み合わせることで、より実践的なデータ処理が可能になります。
初学者のうちは「nrを条件に使う」というシンプルな発想から始めるのがおすすめです。
そこから少しずつ演算子や他の変数と組み合わせていくことで、awkの本来の強力さを実感できるようになります。

![[sed] 実行して理解 指定した範囲の行を削除 文字列のsed](https://running-terminal-commands.com/wp-content/uploads/thumbnail_sed_1920_1080.png.webp)