labunix's blog

labunixのラボUnix

20131222 第8回シェル芸勉強会を解いてみた。

201312228回シェル芸勉強会を解いてみた。

 シェル芸勉強会スライド一覧
 http://blog.ueda.asia/?page_id=684

問題1

・二つずつ数字をフリップしてください。

・例
 入力:1 2 3 4 5 6 7 8 9 10
 出力:2 1 4 3 6 5 8 7 10 9

■ほい。

$ echo `seq 1 10` | sed s/"\([0-9]\) \([0-9]*\)"/"\2 \1"/g
2 1 4 3 6 5 8 7 10 9

問題2
 ・「ユニケージ」「ユニゲージ」「UPS」「USP」の各個数を 数えてください。

 ユニゲージユニケージユニゲージUSP友の会USP友の会 UPS友の会UPS友の会

■ノーマルに解く。

$ echo "ユニゲージユニケージユニゲージUSP の会USP友の会UPS友の会UPS友の会" | \
  sed s/"ユニケージ\|ユニゲージ\|USP\|UPS"/"\n&\n"/g | grep -v "^$\|友の会" | sort | uniq -c
      2 UPS
      2 USP
      1 ユニケージ
      2 ユニゲージ

問題3

 ・次の4個のファイルを作り、同じ内容のものを   探し出すワンライナーを作成してください。

 echo  12345  >  file1
 echo  23456  >  file2
 echo  12345  >  file3
 echo  45678  >  file4

■ハッシュを使わない方法

$ echo 12345 > file1;echo 23456 > file2;echo 12345 > file3;echo 45678 > file4
$ cat file[1-4] | sort | uniq -c | awk '($1>1){print $2}' | grep `xargs` file[1-4] | awk -F\: '{print $1}'
file1
file3

問題4

 ・数字の列を偶数と奇数に分けてください。ただし、偶数、奇数の列内での数字の並びを変えないように。 

 ・例
  入力:3 8 2 10 1 8 9
  出力:8 2 10 8 3 1 9

■変わったことはしない。

$ echo "3 8 2 10 1 8 9" | tr ' ' '\n' | \
  awk '{if($1%2==0){even=even " " $1}else{odd=odd " " $1}};END{print even odd}'
 8 2 10 8 3 1 9

問題5

 ・次のように連続した01の数を数え、次のように変換してください
  01が連続したときは0 or 1の後ろに個数をつけてスペースを挿入
  01が連続していないときはスペース区切りでそのまま出力

 入力:000001111111111001010
 出力:05  110  02  1  0  1  0

■説明文の下の行から処理。

$ echo "000001111111111001010" | sed s/"."/"&\n"/g | uniq -c | \
  awk '{if($1==1){print $2" "}else{print $2$1" "}}' | tr -d '\n';echo
05 110 02 1 0 1 0  

問題6

 ・数字の列を次のように整形してください
  小さい順に空白区切りで並んだ自然数に対し、2個以上の数字が連続した場合は両端の数字だけ残して間にハイフンを入れる
 例
  入力:1 2 3 5 6 8 10 11 12 15
  出力:1-3 5-6 8 10-12 15
シェル芸勉強会スライド一覧
 http://blog.ueda.asia/?page_id=684
■「5-6」が少し強引。

$ echo "1 2 3 5 6 8 10 11 12 15" | \
  sed s/"[0-9]* [0-9]* "/"&\n"/g | awk '{if($2==$1+1){print $1"-"$2"-"}else{print}}' | \
  tr -d '\n' | sed s/"-[0-9]*-"/"-"/g | sed s/"-[0-9]* "/"&\n"/g | \
  sed s/"[0-9]* [0-9]* "/"&\n"/g | awk '{if($2==$1+1){print $1"-"$2"-"}else{print}}' | \
  sed s/"-\$"/" "/g | tr -d '\n';echo
1-3 5-6 8 10-12 15

問題7

 ・次の文字列は、数字3桁の安直なパスワードをMD5ハッシュしたものです。パスワードを破ってください。
  「250cf8b51c773f3f8dc8b4be867a9a02」
  注意:MD5値を求めるときには改行記号を入れていません。

■breakで見つかったら処理終了。

$ for n in `seq -w 0 999`;do \
    echo -n "$n" | md5sum | grep 250cf8b51c773f3f8dc8b4be867a9a02 > /dev/null && echo $n && break; \
  done
456

問題8

 ・/usr/share/dict/wordsでしりとりを完成させてください
  8つ以上単語を並べること

■辞書からのword数を減らしたところで力尽きたのでズルをした。
 実際にしりとりのボキャブラリを増やしたいならこっち。

$ sudo apt-get install -y wamerican
$ sed s/"^[a-z]"/"___&"/ /usr/share/dict/words | grep ^___ | grep -v "'" | sed s/"___"//g | \
  grep "^a.*a\$" | head -8
abracadabra
abscissa
acacia
academia
addenda
agenda
aha
alfalfa