■20131222 第8回シェル芸勉強会を解いてみた。 シェル芸勉強会スライド一覧 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 ・次のように連続した0と1の数を数え、次のように変換してください 0と1が連続したときは0 or 1の後ろに個数をつけてスペースを挿入 0と1が連続していないときはスペース区切りでそのまま出力 入力: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