【実務の事例付き】awkコマンド使い方やの活用事例を紹介

Uncategorized

awkは、テキストデータの加工や抽出が行えるコマンドです。OSの構築時の確認や、ログの絞り込みなどで活用されることがあります。

なお、awkはできることが多い反面、扱いが難しいコマンドの1つです。

この記事では、現役インフラエンジニアの私が、実務でのawkコマンドの活用事例や扱い方を紹介します。実務でリアルに行ってきた方法を紹介するので、インフラエンジニアの方はぜひ最後までお読みください。

awkコマンドとは?

awkはプログラミング言語の1つで、パターンに一致する行の抽出や、テキストデータの処理などが行えます。

実務の中では、下記のようなタスクを行う際に扱われます。

  • ログから特定の行の抽出
  • 時間単位あたりのログの抽出
  • コマンドの実行結果から特定の行み表示させる

今回は一例として紹介していますが、汎用性が高く多くの処理が行えるコマンドです。

awkの基本構文

awkコマンドを実行する際の基本的な構文は、下記のとおりです。

awk [オプション] '{スクリプト}' ファイル名

入力をパイプで行う場合の例は下記のとおりです。

cat /etc/hosts | awk 'コマンド'

awkコマンド書き方は。awkの後に’(シングルクォーテーション)を書きます。‘の中に行いたい処理を書くことで、操作が行えます。

なお、オプションは「-F」を使用することが多いです。オプションが無い場合、空白でフィールドが区切られます。「-F」をつけることで、区切り文字の指定が行えるため、使用されることの多いオプションです。

基本的な使用方法

ここでは、awkコマンドの基本的な使用方法を紹介します。なお、この章ではオプション無の空白区切りと、空白以外で区切る場合の2パターンを紹介します。

通常の空白で区切る場合

例えば、下記のようなファイルがあるとします。

[centos02@localhost ~]$ cat awktest
id name department age salary city score
1001 Tanaka Sales 28 420000 Tokyo 82
1002 Sato Engineering 35 680000 Osaka 91
1003 Suzuki Sales 42 550000 Tokyo 76
1004 Takahashi HR 31 480000 Nagoya 88
1005 Watanabe Engineering 26 520000 Tokyo 95

名前や年齢などをまとめたデータから、idのみを抽出したいとします。その場合下記のコマンドを実行することで、idのみを抽出できます。

awk ‘{print $1}’ awktest

[centos02@localhost ~]$ awk '{print $1}' awktest
id
1001
1002
1003
1004
1005

実行例の場合、コマンドを細かく解説すると下記のとおりです。

コマンドの解説
  • オプション無 → 空白区切り
  • print → 一致する行に対して行う操作 ※printなのでターミナルへの出力
  • $1 → 空白区切りのフィールドの指定 ※$1なので1つ目のフィールド
  • awktest → ファイル名

例えば「name」のみを出したい場合には$1の部分を$2と変更することで行えます。

空白以外で区切りたい時

なお、データによっては、空白ではない部分で区切りたい時もあるでしょう。例えば、先ほどのデータがカンマ区切りだったとします。

[centos02@localhost ~]$ cat awktest2
id,name,department,age,salary,city,score
1001,Tanaka,Sales,28,420000,Tokyo,82
1002,Sato,Engineering,35,680000,Osaka,91
1003,Suzuki,Sales,42,550000,Tokyo,76
1004,Takahashi,HR,31,480000,Nagoya,88
1005,Watanabe,Engineering,26,520000,Tokyo,95

この場合空白が無いので「awk ‘{print $1}’ awktest」と実行しても、idのみ抽出は行えません。空白以外を区切り対象とする場合には「-F」オプションを使用します。

上記の例でidのみを抽出したい場合のコマンドは、下記のとおりです。

awk -F “,” ‘{print $1}’ awktest2

-Fオプションの後に指定した文字で、区切られるように変更できます。

[centos02@localhost ~]$ awk -F "," '{print $1}' awktest2
id
1001
1002
1003
1004
1005

実務での実行例

ここでは、インフラエンジニアとして働いた中で、実務の中で実際にawkコマンドを使用した例を紹介します。

ファイルから特定の行の抽出

awkを扱うことで、ファイルの特定の行の抽出が行えます。先ほどの「基本的な使用方法」の章でも例としてあげましたが、実務の中でも活用する場面が多いです。

例えば、/var/log/messagesにが下記のようになっているとします。

Jul 18 09:12:01 rhel82-server systemd[1]: Starting Session 12 of user root.
Jul 18 09:12:01 rhel82-server systemd[1]: Started Session 12 of user root.
Jul 18 09:15:03 rhel82-server sshd[2381]: pam_unix(sshd:session): session opened for user admin(uid=1000) by (uid=0)
Jul 18 09:20:11 rhel82-server systemd[1]: Starting Cleanup of Temporary Directories…
Jul 18 09:20:11 rhel82-server systemd[1]: Finished Cleanup of Temporary Directories.
Jul 18 09:30:45 rhel82-server kernel: [12345.678901] eth0: link up, 1000 Mbps full duplex
Jul 18 09:45:00 rhel82-server chronyd[721]: Selected source 169.254.169.123 (pool.ntp.org)
Jul 18 10:00:01 rhel82-server systemd[1]: Starting dnf makecache…
Jul 18 10:00:15 rhel82-server systemd[1]: Finished dnf makecache.
Jul 18 10:12:35 rhel82-server systemd[1]: Stopped The Apache HTTP Server.
Jul 18 10:12:35 rhel82-server systemd[1]: Starting The Apache HTTP Server…
Jul 18 10:12:36 rhel82-server systemd[1]: Started The Apache HTTP Server.
Jul 18 10:20:07 rhel82-server kernel: [12456.112233] Out of memory: Killed process 4521 (java) total-vm:2048576kB, anon-rss:512000kB

この中から時刻だけを抜きたい場合、下記のコマンドで行えます。

[centos02@localhost ~]$ cat messages | awk '{print $3}'
09:12:01
09:12:01
09:15:03
09:20:11
09:20:11
09:30:45
09:45:00
10:00:01
10:00:15
10:12:35
10:12:35
10:12:36
10:20:07

この感じで特定の行のみ欲しい場合に扱うことが多いです。

コマンド実行時の表示の絞り込み

コマンドの標準出力を絞り込むことで、確認したい部分の視認性をあげるのに使うことがあります。

実例で「df -h」の中から、ファイルシステム・使用・残りの3つのみに絞り込みたいと思います。下記のコマンドで行えます。

df -h | awk ‘{print $1,$3,$4}’

複数のフィールドを指定する場合には、カンマで区切ることで行えます。

[centos02@localhost ~]$ df -h | awk '{print $1,$3,$4}'
ファイルシス 使用 残り
/dev/mapper/cs-root 6.8G 9.3G
devtmpfs 0 822M
tmpfs 0 853M
tmpfs 6.8M 335M
tmpfs 0 1.0M
/dev/sda2 564M 1.4G
tmpfs 72K 171M
tmpfs 56K 171M

ファイルシステムの文字の長さからフォーマットが若干崩れますが、情報の選定が行えます。なお、表示させる内容を整えたい場合には、パイプで「column -t」とつけることで、入力をテーブル形式に自動整形してくれます。

こちらはテキストデータのみだとわかりづらいため、実際の写真を添付します。

ログファイルから特定の条件での絞り込み

続いては、ログファイルの中から特定の条件で絞り込みが行えます。実務では、特定の時刻のログを確認したい際に扱うことが多いです。

ログファイルの中には、非常に多い数のログが出力されています。その中から、特定の30分のみのログだけを表示させたい場合に便利です。

例えば、下記のログの中から「09:30:00」までのログを表示させたいとします。

Jul 18 09:12:01 rhel82-server systemd[1]: Starting Session 12 of user root.
Jul 18 09:12:01 rhel82-server systemd[1]: Started Session 12 of user root.
Jul 18 09:15:03 rhel82-server sshd[2381]: pam_unix(sshd:session): session opened for user admin(uid=1000) by (uid=0)
Jul 18 09:20:11 rhel82-server systemd[1]: Starting Cleanup of Temporary Directories…
Jul 18 09:20:11 rhel82-server systemd[1]: Finished Cleanup of Temporary Directories.
Jul 18 09:30:45 rhel82-server kernel: [12345.678901] eth0: link up, 1000 Mbps full duplex
Jul 18 09:45:00 rhel82-server chronyd[721]: Selected source 169.254.169.123 (pool.ntp.org)
Jul 18 10:00:01 rhel82-server systemd[1]: Starting dnf makecache…
Jul 18 10:00:15 rhel82-server systemd[1]: Finished dnf makecache.
Jul 18 10:12:35 rhel82-server systemd[1]: Stopped The Apache HTTP Server.
Jul 18 10:12:35 rhel82-server systemd[1]: Starting The Apache HTTP Server…
Jul 18 10:12:36 rhel82-server systemd[1]: Started The Apache HTTP Server.
Jul 18 10:20:07 rhel82-server kernel: [12456.112233] Out of memory: Killed process 4521 (java) total-vm:2048576kB, anon-rss:512000kB

その場合、下記のコマンドで絞り込みが可能です。

awk ‘$3 <= “09:30:00″‘

[centos02@localhost ~]$ cat messages | awk '$3 <= "09:30:00"'
Jul 18 09:12:01 rhel82-server systemd[1]: Starting Session 12 of user root.
Jul 18 09:12:01 rhel82-server systemd[1]: Started Session 12 of user root.
Jul 18 09:15:03 rhel82-server sshd[2381]: pam_unix(sshd:session): session opened for user admin(uid=1000) by (uid=0)
Jul 18 09:20:11 rhel82-server systemd[1]: Starting Cleanup of Temporary Directories…
Jul 18 09:20:11 rhel82-server systemd[1]: Finished Cleanup of Temporary Directories.

解説を少し交えます。

解説

awk ‘$3 → こちらはオプション無なので、空白区切りの3つ目のフィールドを指します。今回の場合だと時刻です。

<= “09:30:00” → 条件に合致する値が09:30:00より小さいもののみを指定します。

ログファイルの操作の中では、時刻での絞り込みで使用される場面が一番多かったです。扱えると非常に汎用性が高いので、何度も練習して扱えるようにしておきましょう。

コメント

タイトルとURLをコピーしました