ワンライナーのための awk の必要最小限メモ
2015-09-09-2
[Programming]
awk はテキスト形式のデータの処理を得意とするプログラミング言語。sed と同じで、複雑なことは苦手だけど手軽で便利。
以下、ワンライナー利用を前提とした awk の必要最小限のメモ。
指定フィールド(カラム)を表示:
条件にあったら出す:
正規表現:
正規表現でのマッチ箇所の取り出し・後方参照・文字列置換:
空行を無視:
区切り文字を指定:
数値の合計:
ラベルで集計:
標準偏差と偏差値:
辞書とマッチするカラムを置き換える:
昔、「awk から多く学ぼう!」と言いながらいろいろやったけどそれほど多くは学べず、結局「大は小を兼ねる」で Perl を使ってる。Perl はテキスト・データ処理以外もできるし、柔軟性も汎用性も高い。
awk って、文字列置換まわりが sed 仕様だったら良かったんだけどねえ。って、それが Perl か。
以下、ワンライナー利用を前提とした awk の必要最小限のメモ。
レシピ
指定フィールド(カラム)を表示:
awk '{print $1}' awk '{print $3,$2}'
条件にあったら出す:
awk '$1 > 0 {print $2} $1 <= {print $1}' awk '$1=="P" {print NR, $0}' awk '{if($1<-1 || 5<$1) print}' awk '{if($1>0 && $1<10)print"P";else print}'
正規表現:
awk '/RT/ {print NR,$0}' awk '$2~/RT/ {printf("%06d %s\n", NR,$1)}'
正規表現でのマッチ箇所の取り出し・後方参照・文字列置換:
awk 'match($0, /(P|N)/) {print substr($0, RSTART, RLENGTH)}' gawk {'print gensub(/^(.)\t/,"[\\1] ","g",$0)'}
空行を無視:
awk 'NF > 0 {print $1}' awk '!/^$/ {print}'
区切り文字を指定:
awk -F'\t' '$2~/です/ {print sprintf("%06d %s", NR,$0)}' awk -F, '{print NR,$3}' awk -F' ' '{print $2}' echo "A,1 B,2 C,3" | awk 'BEGIN{FS=",";RS=" ";OFS="\t"}{print$1,$2}'
数値の合計:
awk '{s+=$1}END{print s}' awk 'BEGIN{print"NUM","SUM1","SUM2"}{s1+=$1;s2+=$2}END{print NR,s1,s2}' awk 'BEGIN{OFMT="%.2f";print"NUM","VAL","CUM"}{s+=$1;print NR,$1,s}'
ラベルで集計:
echo "A 9\nB 2\nC 3\nA 5\nB 4" |\ awk '{s[$1]+=$2}END{for(k in s){print k" "s[k]}}'
標準偏差と偏差値:
(ref. 【Perl】標準偏差と偏差値の計算[2010-07-28-4])echo "12\n67\n25\n37\n52\n40\n13\n29\n5\n93" |\ awk '{s+=$1;v[NR]=$1}END{a=s/NR;for(i in v){r+=(v[i]-a)^2};print sqrt(r/NR)}' echo "12 67 25 37 52 40 13 29 5 93" |\ awk 'BEGIN{RS=" "}{s+=$1;v[NR]=$1}END{a=s/NR; for(i in v){r+=(v[i]-a)**2};sd=sqrt(r/NR); for(i=1;i<=NR;i++){print v[i],(v[i]-a)/sd*10+50}}'
辞書とマッチするカラムを置き換える:
(ref. 【Perl】辞書とマッチするカラムを別なものに置換する【ワンライナー】[2015-09-01-4])cat a.dic ABC 1 MNO 2 XYZ 3 cat a.txt 104 ABC this 780 MNO is 459 XYZ pen 482 ABC it awk '!f{f=FILENAME}{if(f==FILENAME){d[$1]=$2}else {if(d[$2]){print$1,d[$2],$3}else{print}}}' a.dic a.txt 104 1 this 780 2 is 459 3 pen 482 1 it
オプション・変数・関数
- "-F" : 区切り文字を指定
- $0 : 読み込んだ行の全体
- NR : 行の数、行番号
- NF : 列の数、フィールド数(カラム数)
- FILENAME : 読み込んでるファイル名
- RS : 入力の行区切り文字
- FS : 入力の列区切り文字 ("-F"オプション)
- ORS : 出力の行区切り文字
- OFS : 出力の列区切り文字
- OFMT : 数値の出力形式
- BEGIN{}, END{} : 読み込み前と読み込み後に実行
- cos, exp, getline, index, int, length, log, match, sin, split, sprintf, sqrt, substr
- if, while, do, for, break, continue, print, printf, next, exit, delete
コメント
昔、「awk から多く学ぼう!」と言いながらいろいろやったけどそれほど多くは学べず、結局「大は小を兼ねる」で Perl を使ってる。Perl はテキスト・データ処理以外もできるし、柔軟性も汎用性も高い。
awk って、文字列置換まわりが sed 仕様だったら良かったんだけどねえ。って、それが Perl か。
参考
- AWKコマンドの使い方
http://itref.fc2web.com/unix/awk.html - なるべく書かないawkの使い方 - ザリガニが見ていた...。
http://d.hatena.ne.jp/zariganitosh/20131209/minimum_awk - The GNU Awk User's Guide - Table of Contents
http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_toc.html - awk コマンド | コマンドの使い方(Linux) | hydroculのメモ
https://hydrocul.github.io/wiki/commands/awk.html
この記事に言及しているこのブログ内の記事