Bashプログラミング
 Computer >> コンピューター >  >> プログラミング >> Bashプログラミング

Awkの基本を完全マスター:知っておきたいprintコマンド7選を実例つきで解説

Awkの基本を完全マスター:知っておきたいprintコマンド7選を実例つきで解説

本記事は、Awkチュートリアルシリーズの第1回目です。今後数週間にわたり、実用的なサンプルとともにAwkの全機能を網羅した記事を順次公開していく予定です。

この記事では、Awkの基本的な動作メカニズムを確認しながら、実際に役立つ7つのawk printコマンドの使用例を見ていきましょう。

注意: まだの方は、以前公開したSedチュートリアルシリーズもあわせてご覧ください。

Awkの概要と印刷(出力)操作の基礎

Awkは、構造化データを簡単に操作し、整形されたレポートを生成できるプログラミング言語です。「Awk」という名前は、開発者3名である「Aho(アホ)」「Weinberger(ワインバーガー)」「Kernighan(カーニハン)」の頭文字に由来しています。

Awkは主にパターンのスキャンと処理に使われます。1つまたは複数のファイルを走査し、指定したパターンに一致する行が含まれているかを調べ、一致した場合に関連付けられたアクションを実行します。

Awkの主な特徴は以下のとおりです。

  • Awkはテキストファイルを「レコード」と「フィールド」の単位で扱う。
  • 一般的なプログラミング言語と同様に、変数・条件分岐・ループを使用できる。
  • 算術演算子や文字列演算子を備えている。
  • 整形されたレポートを生成できる。

Awkはファイルまたは標準入力からデータを読み込み、結果を標準出力へ出力します。なお、テキスト以外のファイルの扱いは苦手です。

Syntax:
awk '/search pattern1/ {Actions}
 /search pattern2/ {Actions}' file

上記のawk構文における各要素は次のとおりです。

  • search pattern(検索パターン):正規表現を指定する。
  • Actions(アクション):実行するステートメントを記述する。
  • Awkでは複数のパターンとアクションを組み合わせられる。
  • file:入力ファイルを指す。
  • プログラム全体をシングルクォートで囲むのは、シェルに特殊文字を解釈させないためである。

Awkの動作メカニズム

  1. Awkは入力ファイルを1行ずつ読み込む。
  2. 各行に対し、指定された順序でパターンとの照合を行い、一致すれば対応するアクションを実行する。
  3. どのパターンにも一致しなければ、アクションは実行されない。
  4. 上記の構文では、検索パターンまたはアクションのどちらか一方のみ省略できる(両方の省略は不可)。
  5. 検索パターンを省略した場合、Awkは入力のすべての行に対してアクションを実行する。
  6. アクションを省略した場合、「一致した行をすべて表示する」のがデフォルトの動作となる。
  7. 空の中括弧「{}」だけでは何も実行されない。デフォルトの表示処理も行われないので注意。
  8. アクション内の各ステートメントはセミコロンで区切る必要がある。

それでは、以下の内容を持つemployee.txtファイルを作成しましょう。このファイルは以降の例すべてで使用します。

$cat employee.txt
100 Thomas Manager Sales $5,000
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000

Awk 例1:Awkのデフォルト動作

デフォルトでは、Awkはファイル内のすべての行をそのまま表示します。

$ awk '{print;}' employee.txt
100 Thomas Manager Sales $5,000
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000

この例ではパターンが指定されていないため、アクションはすべての行に適用されます。引数なしのprintアクションは、デフォルトで行全体を表示します。そのため、ファイル内の全行がそのまま出力されます。なお、アクションは中括弧「{ }」で囲む必要がある点に注意してください。

Awk 例2:パターンに一致する行だけを表示する

$ awk '/Thomas/
> /Nisha/' employee.txt
100 Thomas Manager Sales $5,000
400 Nisha Manager Marketing $9,500

この例では、「Thomas」または「Nisha」に一致するすべての行を表示しています。ここでは2つのパターンを使用しました。Awkは任意の数のパターンを受け付けられますが、各セット(パターンと対応するアクション)は改行で区切る必要があります。

Awk 例3:特定のフィールドだけを表示する

Awkには多数の組み込み変数が用意されています。各レコード(=各行)について、デフォルトでは空白文字を区切りとしてレコードが分割され、$n 変数に格納されます。行に4つの単語がある場合、それぞれ $1、$2、$3、$4 に格納されます。$0 は行全体を表します。また、NF はレコード内のフィールド総数を表す組み込み変数です。

$ awk '{print $2,$5;}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000
$ awk '{print $2,$NF;}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000

上の例では、$2 が名前(Name)、$5 が給与(Salary)を表しています。$NF は最後のフィールドを意味するため、これを使っても同じく給与を取得できます。print文の中の「,(カンマ)」は連結子(セパレータ)として機能します。

Awk 例4:初期化(BEGIN)と最終処理(END)

Awkには、BEGINとENDというキーワードで指定される2つの重要な特殊パターンがあります。

Syntax: 
BEGIN { Actions}
{ACTION} # Action for everyline in a file
END { Actions }
# is for comments in Awk

BEGINセクションで指定されたアクションは、入力から行を読み込み始めるに実行されます。ENDのアクションは、入力行の読み込みと処理が完了したに実行されます。

$ awk 'BEGIN {print "Name\tDesignation\tDepartment\tSalary";}
> {print $2,"\t",$3,"\t",$4,"\t",$NF;}
> END{print "Report Generated\n--------------";
> }' employee.txt
Name Designation Department Salary
Thomas Manager Sales $5,000
Jason Developer Technology $5,500
Sanjay Sysadmin Technology $7,000
Nisha Manager Marketing $9,500
Randy DBA Technology $6,000
Report Generated
--------------

この例では、レポートの見出し(ヘッダー)と末尾のフッター部分が出力されています。

Awk 例5:社員IDが200より大きい社員を抽出する

$ awk '$1 >200' employee.txt
300 Sanjay Sysadmin Technology $7,000
400 Nisha Manager Marketing $9,500
500 Randy DBA Technology $6,000

この例では、第1フィールド($1)が社員IDです。$1 が200より大きい場合、デフォルトのprintアクションが実行され、行全体が表示されます。

Awk 例6:技術部(Technology)所属の社員一覧を表示する

部署名は第4フィールドにあるため、$4 が文字列「Technology」に一致するかどうかを判定し、一致すればその行を表示します。

$ awk '$4 ~/Technology/' employee.txt
200 Jason Developer Technology $5,500
300 Sanjay Sysadmin Technology $7,000
500 Randy DBA Technology $6,000

演算子「~」は正規表現との比較に使用します。一致した場合はデフォルトのアクション、つまり行全体の表示が実行されます。

Awk 例7:技術部(Technology)の社員数をカウントする

次の例では、部署がTechnologyであるかどうかを判定し、該当する場合はアクション内でcount変数をインクリメントします。count変数はBEGINセクションで0に初期化されています。

$ awk 'BEGIN { count=0;}
$4 ~ /Technology/ { count++; }
END { print "Number of employees in Technology Dept =",count;}' employee.txt
Number of employees in Tehcnology Dept = 3

そして処理の最後にcountの値を表示することで、技術部の社員数(この例では3名)がわかります。

おすすめの関連書籍

Awkの基本を完全マスター:知っておきたいprintコマンド7選を実例つきで解説Sed and Awk 101 Hacks(Ramesh Natarajan著)。筆者は毎日UNIX/Linux環境でテキストファイル(データ、設定、ログファイルなど)を扱っており、テキスト加工のあらゆる作業にSedとAwkを活用しています。その長年の経験をもとに執筆した電子書籍「Sed and Awk 101 Hacks」には、SedとAwkのさまざまな高度な機能に関する101の実用例が収録されており、あなたのUNIX/Linuxでの作業をより快適にしてくれるはずです。何年もSedとAwkを使ってきた方でも、まだこの本を読んでいないなら、ぜひ手に取ってみてください。これらのユーティリティの潜在能力にきっと驚かされることでしょう。

その他のAwk関連記事

  • Awkユーザー定義変数の使い方(実例3選)
  • 強力なAwk組み込み変数8選 ― FS、OFS、RS、ORS、NR、NF、FILENAME、FNR
  • Awkの演算子7種類を実例で解説(単項・二項・算術・文字列・代入・条件・正規表現)
  • Awkのif文の使い方4例(if、if else、if else if、三項演算子)
  • Awkのループ処理まとめ:while、do while、forループ、break、continue、exitの使い方
  1. screenFetchとNeofetchでLinuxシステム情報を美しく表示・共有する方法

    自分のLinux環境の設定を他の人と共有したい理由はさまざまです。システムのトラブルシューティングで助けを求めたい場合もあれば、自分が作り上げたデスクトップ環境を誇らしく思って、オープンソース愛好家の仲間に披露したい場合もあるでしょう。 cat /proc/cpuinfo や lscpu コマンドを使えば、一部の情報はBashプロンプトから取得できます。しかし、OS、カーネル、稼働時間(アップタイム)、シェル環境、画面解像度といったより詳細な情報をまとめて共有したいなら、「screenFetch」と「Neofetch」という2つの優れたツールがおすすめです。 ScreenFetchとは Scr

  2. Powerline – VimエディターとBashターミナルに強力なステータスラインとプロンプトを追加する方法

    Powerlineは、Pythonで開発された高機能なステータスラインプラグインです。Vimエディターはもちろん、bash、zsh、tmuxなど、さまざまなアプリケーションに対して美しく情報量の多いステータスラインとプロンプトを提供します。開発者にとって視認性が高く、作業効率を向上させる人気のツールです。 Powerlineの主な特徴 Pythonで実装されているため、拡張性が高く豊富な機能を備えています。 安定性とテスト性に優れたコードベースで、Python 2.6以降およびPython 3に対応しています。 複数のLinuxユーティリティやツールに対するプロンプト・ステータスラインをサ