USP友の会会長が出題した前半戦を解いてみた。

■USP友の会会長が出題した前半戦を解いてみた。

 hbstudy #38 で講師してきました
 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:集計(中級)
 ランダム数を0109の間に収めて頻度分布を作成。

$ 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}'
  09    6
 1019    8
 2029    9
 3039   15
 4049    7
 5059   10
 6069    7
 7079   16
 8089   13
 9099    5
100109   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 

■おまけ。
 問題4100の倍数で作ると、パーセントとして扱いやすい。
 以下のように百万だとほぼ均等になる。

$ 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}'
  09   16
 1019    8
 2029   11
 3039    9
 4049    6
 5059   14
 6069    6
 7079   15
 8089    5
 9099    5
100109    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)}'
  09    8
 1019    8
 2029    7
 3039    9
 4049   10
 5059    8
 6069    7
 7079   10
 8089   10
 9099   10
100109    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)}'
  09    8
 1019    9
 2029    9
 3039    9
 4049    9
 5059    9
 6069    9
 7079    8
 8089    8
 9099    9
100109    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)}'
  09    9
 1019    9
 2029    9
 3039    9
 4049    8
 5059    9
 6069    9
 7079    9
 8089    9
 9099    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)}'
  09  9.093200
 1019  9.148100
 2029  9.106400
 3039  9.112300
 4049  9.086200
 5059  9.052900
 6069  9.092800
 7079  9.117500
 8089  9.072200
 9099  9.062100
100109  9.056300