awkコマンドでパターン検索、テキスト処理をする①
はじめに
くーばねてすをやっつけるためにLinuxさんと仲良くさせていただいているが、Linuxさんには超大量のテキストがあって、検索するだけではなくたくさんテキスト編集処理もする。
今回はテキストを便利に編集できるように非対話型エディタのawkコマンドを勉強しようと思う。
sedコマンドよりさらに強いやつらしい。
概要
■awkコマンドとは
■printとフィールド(列)検索
■パターンの指定
をまとめた!
awkコマンドとは
awkコマンドはsedコマンドのようにワンライナーで編集を指定し編集結果を表示させる。
「sedコマンドよりさらに高機能なテキスト処理に特化したプログラミング言語である。
本格的なテキスト編集ではRubyやPhythonのようなスクリプト言語が多く使われるがawkもまだまだ多くの場面で使われている。」
らしい('_')難しそう。
awkコマンドの書式
$ awk 'パターン{アクション}' ファイル
そしてawkコマンドのスクリプトは以下のようになる
'パターン {アクション}'
まってパターンってだれ('_')
■パターンとは
アクションを実行するかどうかの条件のこと。
awkでは処理中に読み込んでいく1行の入力テキストを「レコード」という。
パターンは省略することが可能でその場合はすべてのレコード(行)にアクションが実行される。
■printとフィールド(列)指定
awkコマンドで最もよく使われるのが特定のフィールドを抽出して表示する列選択だ。
あるディレクトリのの中をls -lで出力してその結果を編集して、ファイルサイズとファイル名だけを出力してみる。ファイルサイズは5列目、ファイル名は9列目になる。
その行を指定して表示するためのスクリプトは
$ '{print $指定行}'
となる。
ディレクトリのなかの5行目と9行目を表示する。
$ ls -l /usr/bin | awk '{print $5,$9}'
24576 .
155 ..
37256 [
107744 a2p
28712 ac
15640 acpi_listen
28968 addr2line
29 alias
略
できた!
ちなみに行指定の間に , を入れないでスペースで空けると、
$ ls -l /usr/bin | awk '{print $5 $9}'
24576.
155..
37256[
107744a2p
28712ac
略
となる。
きゅってなって見づらいから,つけたほうがいいね('_')!
まってこんなの前にどっかでやったことあるな!
区切り文字がある内容のファイルで指定した列だけを抽出した
$ cut -d 区切り文字 -f フィールド(列)指定 ファイル名
ににてる!cutコマンドでも同じように出来るかな?って思いやってみたんだけどスペース区切りの指定の仕方がうまくできなかった。。。_| ̄|○
$ ls -l /usr/bin | cut -d ' ' -f 5,9
ちがうの?
逆にcutコマンドでやってみた中身が:で区切られているファイルを
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin略
$ cat /etc/passwd | awk '{print $4,$5}'
何も表示されなかった...
区切り文字がある時は
cutコマンド、
区切り文字がない時は
awk {print ...}
でしか表示されないのかな?('_')
ともかく、awkコマンドの列指定は
$列指定
となる。
↓$3 ↓$5 ↓$7 ↓$9
-rw-r--r-- 1 root root 0 Jan 2 13:20 .bash
↑$1 ↑$2 ↑$4 ↑$6 ↑$8
ちなみに最後の列(一番右)を指定するときは
$NF
となる。
$ ls -l /usr/bin | awk '{print $NF}'
.
..
[
a2p
ac略
最後だけ出てきた!
最後の列から2番目を指定したい時は
$ ls -l /usr/bin | awk '{print $(NF-1)}'
と指定する。()で囲むんだね('_')
■パターンの指定
$ awk 'パターン{アクション}' ファイル
そういえばパターンはどこ行ったの('_')
そっか、↑の列指定ではパターンを省略して全行がアクションの対象になっていたんだね。
そう!パターンって誰!
「awkコマンドでは、こんなパターンだったらこのようにアクションしなさいと指定できる。」
そのパターンさんってそのパターンなんだね^^
文字列のパターンを指定するにはやはり正規表現を使う。
awkで正規表現を使うには/で囲って指定する。
指定したフィールドに対して、正規表現がマッチするかどうか指定するのには
~
を置く。
$ awk '$フィールド ~ /正規表現/ {アクション}' ファイル
------------------------
↑パターンの部分
$ ls -l /usr/bin | awk '$9 ~ /^cp/ {print $5,$9}'
146880 cp
141824 cpio
67920 cpupower
できた!
ちなみにフィールドを指定しなくてもぜんぜんOKで、そのときは~も必要ない。
$ ls -l /usr/bin | awk '/^l/{print $5,$9}'
20 ansible
20 ansible-2
7 ansible-config略
一瞬まとめ
《パターンに行を指定する時》
$ awk '$フィールド ~ /正規表現/ {アクション}' ファイル
《パターンに行を指定しない時》
$ awk '/正規表現/ {アクション}' ファイル
パターン!アクション!ファイル
まとめ
長いから続く^^
Discussion