#1 awkコマンドとは
空白やカンマなどで区切られたファイルを扱うコマンドです。
#2 環境
VMware Workstation 15 Player上の仮想マシンを使いました。
仮想マシンの版数は以下のとりです。
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 8.3.2011
[root@server ~]# uname -r
4.18.0-240.el8.x86_64
[root@server ~]# awk -V
GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2018 Free Software Foundation.
-snip-
#3 awkコマンドの書式
awk [オプション] [パターン] [アクション] [ファイル]
#4 区切り文字の使い方(-F)
##4.1 スペースを区切り文字として使う方法
スペースで区切られたファイルを作成します。
[root@server awk]# vi test.txt
[root@server awk]# cat test.txt
111 222 333
1列目のフィールドを表示してみます。
[root@server awk]# cat test.txt | awk '{print $1}'
111
フィールドの表示順序を変えてみます。
3列目->2列目->1列目の順番で表示してみます。
[root@server awk]# cat test.txt | awk '{print $3,$2,$1}'
333 222 111
区切り文字としてスペースを明示的に指定する場合は、以下のように実行します。
[root@server awk]# cat test.txt | awk -F " " '{print $2,$3}'
222 333
##4.2 カンマを区切り文字として使う方法
カンマで区切られたファイルを作成します。
[root@server awk]# vi test.txt
[root@server awk]# cat test.txt
111,222,333
[root@server awk]# cat test.txt | awk -F "," '{print $2}'
222
##4.3 区切り文字を複数指定する方法([]
)
カンマとコロンで区切られたファイルを作成します。
[root@server awk]# cat test.txt
111,222:333
区切り文字を複数指定する場合は、[]
の中に区切り文字を指定します。
[root@server awk]# cat test.txt | awk -F "[,:]" '{print $1}'
111
[root@server awk]# cat test.txt | awk -F "[,:]" '{print $2}'
222
[root@server awk]# cat test.txt | awk -F "[,:]" '{print $3}'
333
##4.4 タブを区切り文字として使う方法(\t
)
タブで区切られたファイルを作成します。
[root@server awk]# cat test.txt
111 222 333
[root@server awk]# cat test.txt | awk -F "\t" '{print $2}'
222
#5 組み込み変数の使い方
変数名 | 意味 |
---|---|
NR | 現在処理しているレコードの行番号 |
NF | レコード中のフィールド数 |
$0 | レコード |
$n | レコードのn番目のフィールド |
OFS | フィールドの区切り(デフォルトは空白) |
FILENAME | ファイル名 |
##5.1 NR,$0,$nの使い方
[root@server awk]# cat test.txt
111 aaa
222 bbb
333 ccc
処理中のレコードの行番号とレコードを表示してみます。
[root@server awk]# cat test.txt | awk '{print NR,$0}'
1 111 aaa
2 222 bbb
3 333 ccc
2行目のレコードを表示してみます。
[root@server awk]# cat test.txt | awk 'NR==2 {print $0}'
222 bbb
3行目のレコードの2番目のフィールドを表示してみます。
[root@server awk]# cat test.txt | awk 'NR==3 {print $2}'
ccc
##5.2 NFの使い方
[root@server awk]# cat test.txt
aaa
bbb ccc
ddd eee fff
左端がフィールド数を表しています。
1行目は1個、2行目は2個、3行目は3個であることがわかります。
[root@server awk]# cat test.txt | awk '{print NF,$0}'
1 aaa
2 bbb ccc
3 ddd eee fff
##5.3 OFSの使い方
[root@server awk]# cat test.txt
111 aaa
222 bbb
333 ccc
フィールドの区切り文字をコロンで出力してみます。
[root@server awk]# cat test.txt | awk 'OFS = ":" {print $1,$2}'
111:aaa
222:bbb
333:ccc
##5.4 FILENAME の使い方
ファイル名に続いて、各行のレコードを表示してみます。
[root@server awk]# awk '{print FILENAME,$0}' test.txt
test.txt 111 aaa
test.txt 222 bbb
test.txt 333 ccc
#6 正規表現の使い方
##6.1 行頭(^
)
[root@server awk]# cat test.txt
111 aaaa
222 abcd
333 AAAA
行頭が1
ではじまる行を表示してみます。
[root@server awk]# cat test.txt |awk '/^1/ {print $0}'
111 aaaa
##6.2 行末($
)
行末がA
で終わる行を表示してみます。
[root@server awk]# cat test.txt |awk '/A$/ {print $0}'
333 AAAA
##6.3 語頭(\<
)
aa
で始まる単語が含まれる行を検索してみます。
[root@server awk]# cat test.txt | awk '/\<aa/ {print $0}'
111 aaaa
##6.4 語尾(\>
)
AA
で終わる単語が含まれる行を検索してみます。
[root@server awk]# cat test.txt | awk '/\<AA/ {print $0}'
333 AAAA
##6.5 マッチする行を抜き出す方法
bc
を含む行を検索してみます。
[root@server awk]# cat test.txt | awk '/bc/ { print $0 }'
222 abcd
##6.6 マッチしない行を抜き出す方法('!')
bc
を含まない行を検索してみます。
[root@server awk]# cat test.txt | awk '!/bc/ { print $0 }'
111 aaaa
333 AAAA
##6.7 パターン1からパターン2にマッチするまでアクションを実行する方法(/パターン1/,/パターン2/
)
111
ではじまって、222
が出現するまでレコードを表示してみます。
[root@server awk]# cat test.txt |awk '/111/,/222/ { print $0 }'
111 aaaa
222 abcd
#7 実践編
##7.1 デフォルトゲートウェイを取得する方法
[root@server ~]# ip route
default via 192.168.2.1 dev ens33 proto static metric 100
192.168.2.0/24 dev ens33 proto kernel scope link src 192.168.2.115 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
[root@server ~]# ip route | awk '$1=="default" {print $3}'
[root@server ~]# 192.168.2.1
##7.2 ログファイルから特定日時のメッセージを抽出する方法
まずは、抽出元のログファイルを確認します。
日時がApr 18 20:20:18
からApr 18 20:26:33
にマッチするメッセージは
IPv6: MLD:...
になります。
[root@server ~]# cat /var/log/messages|head -n 10
Apr 18 20:20:02 server systemd[1]: httpd.service: Unit cannot be reloaded because it is inactive.
Apr 18 20:20:02 server rsyslogd[1249]: [origin software="rsyslogd" swVersion="8.1911.0-6.el8" x-pid="1249" x-info="https://www.rsyslog.com"] rsyslogd was HUPed
Apr 18 20:20:18 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:22:23 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:24:28 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:26:33 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:28:31 server systemd[1]: Created slice system-user\x2druntime\x2ddir.slice.
Apr 18 20:28:31 server systemd[1]: Created slice User Slice of UID 0.
Apr 18 20:28:31 server systemd[1]: Started /run/user/0 mount wrapper.
Apr 18 20:28:31 server systemd[1]: Starting User Manager for UID 0...
[root@server ~]# cat /var/log/messages|awk '/Apr 18 20:20:18/,/Apr 18 20:26:33/ { print $0 }'
Apr 18 20:20:18 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:22:23 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:24:28 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
Apr 18 20:26:33 server kernel: IPv6: MLD: clamping QRV from 1 to 2!
##7.3 特定のファイルサイズを抽出する方法
/bin配下のファイルサイズが30000000(byte)以上のファイルを抽出してみます。
$5
はls -l
を実行したときの5番目のフィールド(ファイルサイズ)を表します。
[root@server awk]# ls -l /bin/ | awk '$5>=30000000 {print $0}'
-rwxr-xr-x. 1 root root 30057712 2月 22 13:47 buildah
-rwxr-xr-x. 1 root root 53912832 2月 22 13:53 podman
なお、同様のことはfindコマンドを使ってもできます。
findコマンドは、findコマンドの使い方を参照してください。
#Z 参考情報
awkの-Fオプションで区切り文字を指定する方法
【 awk 】コマンド(基本編その4)――テキストの加工とパターン処理、printとprintfの使い方
【 awk 】コマンド(応用編その6)――テキストの加工とパターン処理、複数ファイルの処理
awk コマンド
AWKで一番の得意ワザ! シェルで文字列を自在に扱うための文字列関数
awkを使って特定の日時の範囲でログを抽出する