SDシェル芸人連載からのお勉強

Software Design 2019/07から(問題1)

mkdir shellgei
cd shellgei

wget https://raw.githubusercontent.com/ryuichiueda/ShellGeiData/master/sd201907/user1
wget https://raw.githubusercontent.com/ryuichiueda/ShellGeiData/master/sd201907/user2
wget https://raw.githubusercontent.com/ryuichiueda/ShellGeiData/master/sd201907/user3
wget https://raw.githubusercontent.com/ryuichiueda/ShellGeiData/master/sd201907/user4

awk '{print $0, FILENAME}' user* | sort | \
awk '(pre!=$1){print "";printf $0}(pre==$1){printf " "$2}{pre=$1}' |\
awk 'NF>3'
sort user* | uniq -c | awk '($1>=3){print $2}' | \
grep -f - user* | awk -F":" '{a[$2]=a[$2]" "$1}END{for(k in a){print k""a[k]}}'


これもおもしろい

$ awk '{print $0, "第"FNR"候補", FILENAME}' user*| sort -k1 -k2n |
datamash -s crosstab 2,1 unique 3 -t ' '|sed '1s/^/-/' | column -t

学んだこと

  • awk でセパレータを指定するのって -F":" のように指定できるのか。今まで(FS=":")みたいに書いていた。
  • sort ってそういえばいきなりファイル名を指定してもいいんだね。何故か必ず cat してから、パイプで渡すのがクセになっていた。
  • awk でのセパレータで分けられた列数を見るの、"awk 'NF>3'"。知らなかった。
  • パイプで渡された結果(一覧)を入力ファイルとして受け取る "awk -f -"。いつもこれがわからなくて、遠回りしていた。

問題4

* A B
X 4 2
Y 3 1
* A B C D
X 1 2 3 4
Y 12 34 56 78
Z 3 1 4 1
$ awk 'FNR==1{$1="";h=$0}FNR!=1{print FILENAME, $0,h,NF-1}' data_* |\
 awk '{for(i=NF-$NF;i<NF;i++) print $1, $2, $i, $(i-$NF)}'

学んだこと

  • とりあえず、awkで「1行目に対して」処理したい時は FNR==1 のブロックで扱えば良いらいしことは分かった
  • そのブロックで保持した値(h)をその後の処理で使えるのかー。
  • NF がその行の列数なので、$NF で最終列の値 が取れる。へぇぇ