■USP友の会会長が出題した前半戦を解いてみた。
hbstudy
http://www.usptomo.com/PAGE=20121028HBSTUDY
■問題1:ユーザの抽出(初級)
ユーザの一覧
$ awk -F\: '{print $1}' /etc/passwd | wc -l
33
■問題2:ユーザの抽出2(中級)
bash/shユーザ、どちらが多い?
$ grep '/bin/sh'"\|"'/bin/bash' /etc/passwd | awk -F\: '{print $7}' | sort | uniq -c
3 /bin/bash
18 /bin/sh
■問題3:ファイルの一括変換(中級)
「/etc」以下のシェルスクリプトで「#!/bin/bash」を「#!/usr/local/bin/bash」に変更して、「~/hoge」にコピー。
$ test -d ~/hoge || mkdir ~/hoge; \
sudo find /etc -type f -iname "*.sh" -print | \
for list in `xargs`;do \
grep '#!/bin/bash' $list > /dev/null && sed s%'#!/bin/bash'%'#!/usr/local/bin/bash'%g "$list" \
> ~/hoge/`echo $list | sed s%".*/"%%g`; \
done
■問題4:集計(中級)
ランダム数を0〜109の間に収めて頻度分布を作成。
$ for n in `seq 1 110`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3d\n",($2*10),($2*10)+9,$1}'
0〜 9 6
10〜 19 8
20〜 29 9
30〜 39 15
40〜 49 7
50〜 59 10
60〜 69 7
70〜 79 16
80〜 89 13
90〜 99 5
100〜109 14
■問題5:Fizz Buzz(上級)
3の倍数はFizz、5の倍数はBuzz、15の倍数はFizzBuzz、その他は数を出力。
$ for n in `seq 1 9999`;do \
echo "$n Fizz Buzz" | \
awk '{if($1%15==0)print $2$3;else if($1%3==0)print $2;else if($1%5==0)print $3;else print $1}'; \
done
■おまけ。
問題4は100の倍数で作ると、パーセントとして扱いやすい。
以下のように百万だとほぼ均等になる。
$ for n in `seq 1 100`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3d\n",($2*10),($2*10)+9,$1}'
0〜 9 16
10〜 19 8
20〜 29 11
30〜 39 9
40〜 49 6
50〜 59 14
60〜 69 6
70〜 79 15
80〜 89 5
90〜 99 5
100〜109 5
$ for n in `seq 1 1000`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3d\n",($2*10),($2*10)+9,($1/10.0)}'
0〜 9 8
10〜 19 8
20〜 29 7
30〜 39 9
40〜 49 10
50〜 59 8
60〜 69 7
70〜 79 10
80〜 89 10
90〜 99 10
100〜109 7
$ for n in `seq 1 10000`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3d\n",($2*10),($2*10)+9,($1/100.0)}'
0〜 9 8
10〜 19 9
20〜 29 9
30〜 39 9
40〜 49 9
50〜 59 9
60〜 69 9
70〜 79 8
80〜 89 8
90〜 99 9
100〜109 9
$ for n in `seq 1 100000`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3d\n",($2*10),($2*10)+9,($1/1000.0)}'
0〜 9 9
10〜 19 9
20〜 29 9
30〜 39 9
40〜 49 8
50〜 59 9
60〜 69 9
70〜 79 9
80〜 89 9
90〜 99 9
$ for n in `seq 1 1000000`;do echo $(($RANDOM % 110));done > args
$ awk '{print ($1-($1%10))/10}' args | sort -n | uniq -c | awk '{printf "%3d〜%3d %3f\n",($2*10),($2*10)+9,($1/10000.0)}'
0〜 9 9.093200
10〜 19 9.148100
20〜 29 9.106400
30〜 39 9.112300
40〜 49 9.086200
50〜 59 9.052900
60〜 69 9.092800
70〜 79 9.117500
80〜 89 9.072200
90〜 99 9.062100
100〜109 9.056300