awkコマンドの使い方|パターン検索やフィールド抽出の実践例コマンド


図解60p「Linuxサーバー構築入門マニュアル」無料
登録10秒/自動返信でDL/合わなければ解除3秒
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxコマンド, LinuxコマンドA-E, テキスト処理コマンド > awkコマンドの使い方|パターン検索やフィールド抽出の実践例コマンド
「ログファイルから特定のフィールドだけ抜き出したい」「CSVの特定列だけ表示したい」
こうした場面で真っ先に頼りになるのが、awkコマンドです。

この記事では、awkコマンドの基本構文からフィールド抽出、パターンマッチ、パイプとの組み合わせまで、実務で使える実践的な使い方を解説します。
初心者がつまずきやすいポイントやトラブル対処も網羅しているので、ぜひ最後まで読んでみてください。

awkコマンドとは?テキスト処理の万能ツール

awkは、テキストデータを「行単位」で読み込み、指定したパターンに一致する行に対して処理を実行するコマンドです。

名前の由来は、開発者3名(Aho・Weinberger・Kernighan)の頭文字です。単なるコマンドというよりも、テキスト処理に特化した小さなプログラミング言語と考えてください。

awkが得意なのは、次のような処理です。

特定の列(フィールド)だけを抽出する
条件に一致する行だけを絞り込む
簡単な集計や加工を行う

grep・sed・cutなど他のテキスト処理コマンドと比べて、「列の指定」と「条件分岐」を同時にできるのがawkの強みです。

awkコマンドの基本的な使い方

1. 基本構文を理解する

awkの基本構文は次のとおりです。

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

パターン:どの行を対象にするかの条件(省略すると全行が対象)
アクション:対象行に対して実行する処理(省略するとprint、つまり行の表示)

たとえば、ファイルの全行をそのまま表示するには次のように実行します。

$ awk '{print}' sample.txt

これはcatコマンドと同じ結果ですが、ここからパターンやフィールド指定を加えていくのがawkの本領です。

2. 特定のフィールドを抽出する

awkはデータを自動的にフィールド(列)に分割します。デフォルトの区切り文字はスペースまたはタブです。

各フィールドは $1(1列目)、$2(2列目)のように参照します。$0 は行全体を表します。

# 1列目だけを表示する $ echo "tanaka 営業部 東京" | awk '{print $1}' tanaka # 1列目と3列目を表示する $ echo "tanaka 営業部 東京" | awk '{print $1, $3}' tanaka 東京

3. 区切り文字を指定する(-Fオプション)

デフォルトのスペース/タブ以外の区切り文字を使いたい場合は、-F オプションで指定します。

たとえば /etc/passwd はコロン(:)区切りなので、ユーザー名(1列目)とホームディレクトリ(6列目)を取り出すには次のようにします。

$ awk -F: '{print $1, $6}' /etc/passwd root /root bin /bin daemon /sbin tanaka /home/tanaka

CSV(カンマ区切り)の場合は -F, と指定します。

$ awk -F, '{print $2}' sales.csv 商品名 ノートPC モニター キーボード

4. パターンマッチで行を絞り込む

特定の文字列を含む行だけを処理したい場合は、パターンに正規表現を指定します。

# "error" を含む行だけ表示する $ awk '/error/ {print}' /var/log/messages # 先頭が # で始まるコメント行を除外する $ awk '/^[^#]/ {print}' /etc/httpd/conf/httpd.conf

数値の比較条件も使えます。

# 3列目(UID)が1000以上の行だけ表示する $ awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd tanaka 1000 suzuki 1001

実務で使えるawk活用テクニック

5. 複数条件で絞り込む

条件を組み合わせるには、&&(AND)と ||(OR)を使います。

# UIDが1000以上かつ、シェルが/bin/bashのユーザーを表示 $ awk -F: '$3 >= 1000 && $7 == "/bin/bash" {print $1}' /etc/passwd # "error" または "warning" を含む行を表示 $ awk '/error/ || /warning/' /var/log/messages

6. BEGIN / ENDブロックを使う

BEGIN はデータ処理の前に1回だけ実行されるブロック、END はデータ処理の後に1回だけ実行されるブロックです。
ヘッダーの出力や集計処理で活躍します。

# ヘッダー付きでユーザー一覧を表示する $ awk -F: 'BEGIN {print "ユーザー名 UID"} $3 >= 1000 {print $1" "$3}' /etc/passwd ユーザー名 UID tanaka 1000 suzuki 1001 # 行数をカウントする $ awk 'END {print NR"行"}' /var/log/messages 1523行

7. 組み込み変数を活用する

awkには便利な組み込み変数が用意されています。

NR:現在の行番号(Number of Records)
NF:現在の行のフィールド数(Number of Fields)
FS:入力の区切り文字(Field Separator、-Fと同じ)
OFS:出力の区切り文字(Output Field Separator)

# 行番号付きで表示する $ awk '{print NR": "$0}' /etc/hosts 1: 127.0.0.1 localhost 2: ::1 localhost # 各行の最後のフィールドを表示する $ awk '{print $NF}' sample.txt # 出力の区切り文字をカンマに変更する $ awk -F: 'BEGIN {OFS=","} {print $1, $3, $6}' /etc/passwd root,0,/root tanaka,1000,/home/tanaka

8. パイプと組み合わせる

awkは他のコマンドの出力をパイプで受け取って処理するのが得意です。

# dfコマンドの出力から、使用率が80%以上のファイルシステムを抽出 $ df -h | awk '$5+0 >= 80 {print $6" "$5}' # psコマンドの出力から、メモリ使用量の多い上位5プロセスを表示 $ ps aux | sort -rnk 4 | head -5 | awk '{print $4"% "$11}' # アクセスログからIPアドレスごとのアクセス数を集計 $ awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' /var/log/httpd/access_log | sort -rn | head -10

awkコマンドのトラブルシュートとよくあるミス

「syntax error」が出る場合

awkで最も多いエラーが「syntax error」です。原因のほとんどは、シングルクォートとダブルクォートの使い方のミスです。

awkのプログラム部分は必ずシングルクォートで囲んでください。ダブルクォートで囲むと、シェルが先に変数を展開してしまい、awkに正しい命令が渡りません。

# NG - ダブルクォートで囲んでいる $ awk "{print $1}" sample.txt awk: cmd. line:1: {print } awk: cmd. line:1: ^ unexpected newline or end of string # OK - シングルクォートで囲む $ awk '{print $1}' sample.txt

また、波かっこ { } の閉じ忘れにも注意してください。

フィールドがずれる場合

想定したフィールド番号で正しい値が取れない場合、区切り文字が合っていない可能性があります。

特に注意が必要なのは、連続するスペースの扱いです。awkはデフォルトで連続スペースを1つの区切りとして扱いますが、cutコマンドはそうではありません。

フィールドの内容を確認するには、各フィールドを個別に表示してみましょう。

# 各フィールドの内容を確認する $ echo "aaa bbb ccc" | awk '{for(i=1;i<=NF;i++) print i": "$i}' 1: aaa 2: bbb 3: ccc

タブ区切りを明示的に指定したい場合は -F'\t' を使います。

本記事のまとめ

やりたいこと コマンド
特定の列を表示する awk '{print $1}' ファイル名
区切り文字を指定して列を抽出する awk -F: '{print $1, $6}' /etc/passwd
パターンに一致する行を表示する awk '/パターン/ {print}' ファイル名
数値条件で行を絞り込む awk -F: '$3 >= 1000 {print $1}' /etc/passwd
行数をカウントする awk 'END {print NR}' ファイル名
出力の区切り文字を変更する awk -F: 'BEGIN {OFS=","} {print $1, $3}' /etc/passwd
行番号付きで表示する awk '{print NR": "$0}' ファイル名

awkだけじゃない、Linux全体を体系的に学びませんか?

awkコマンドはテキスト処理の強力な武器ですが、サーバー運用の現場ではこれ以外にも身につけるべきスキルがたくさんあります。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。



無料プレゼント
図解60p「Linuxサーバー構築入門マニュアル」
独学で詰まる前に、“型(手順書)”で最初の環境構築をサクッと終わらせましょう。
登録10秒/自動返信でDL/合わなければ解除3秒
無料で受け取る ※メールアドレスだけでもOK(必須項目は最小限)

宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

<<関連記事>>
・pstree
・chsh
・finger
・duコマンドでディスク使用量を確認する方法|ディレクトリごとの容量や容量順ソートも
・LinuxのOSバージョンを確認するコマンド|uname・os-release・hostnamectlの使い方

図解60pのLinux無料マニュアル
登録10秒/自動返信でDL
無料で受け取る