【問題と解答】第19回シェル芸3周年記念勉強会

Sat Oct 31 17:38:47 JST 2015 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 2708, keywords:USP友の会,勉強会,シェル芸 この記事は最終更新日が6年以上前のものです。

問題のみのページはこちら。

イントロ

第19回シェル芸勉強会イントロ from Ryuichi Ueda

問題で使うファイル等

前回からGitHubに置くようにしました。ファイルは

https://github.com/ryuichiueda/ShellGeiData/tree/master/vol.19

にあります。

クローンは以下のようにお願いします。

$ git clone https://github.com/ryuichiueda/ShellGeiData.git

環境

今回はLinuxで解答例を作りましたので、BSD系、Macな方は以下の表をご参考に・・・。

Mac,BSD系 Linux
gdate date
gsed sed
tail -r tac
gtr tr
gfold fold

Q1

端末で実行すると「1ppm」Žと出力されて、シェルスクリプトに書いて実行すると「40ppm」」と出力されるコマンドの組み合わせを考案してみましょう。フォルクスワーゲンは関係ありません。

解答

例えばbashであれば、シェルスクリプトではaliasが無効になることを利用できます。

$ alias hoge='echo 1ppm' && hoge 2> /dev/null || echo 40ppm
   1ppm
   ###シェルスクリプトにすると挙動が変わる###
   $ cat a
   alias hoge='echo 1ppm' && hoge 2> /dev/null || echo 40ppm
   $ ./a
   40ppm

Q2

二つの自然数を

$ echo 1 4

というようにechoで出力したあと、

4
   3
   2
   1
   2
   3
   4

というように間の数を埋めてみてください。

解答

$ echo 1 4 | while read a b ; do seq $a $b | tac ; seq $a $b ; done | uniq
   4
   3
   2
   1
   2
   3
   4
   ###whileを使わない例###
   $ echo 1 4 | xargs -n 2 seq | xargs | awk '{for(i=NF;i>=1;i--)print $i;print}' | xargs -n 1 | uniq
   4
   3
   2
   1
   2
   3
   4
   ###@ebanさんの答え###
   $ echo 1 4 | (read a b; seq $b -1 $a; seq $[a+1] $b)

Q3

「1234567890」を含む13桁の数字(0から始まる数字を含む)をすべて列挙してみましょう。マイナンバー?何それ?

解答

Macだと最初の答えば000や00が0に削られてうまく動かないようです。

$ echo 1234567890{000..999} {0..9}1234567890{00..99}
    {00..99}1234567890{0..9} {000..999}1234567890 | tr ' ' '\\n' 
   $ seq -w 000 999 | sed 's/./& /g' |
    awk '{a="1234567890"; print $1$2$3a; print $1$2a$3; print $1a$2$3; print a$1$2$3}'
   $ seq -w 000 999 |
    awk '{a="1234567890";for(i=0;i<=3;i++)print substr($1,1,i)a substr($1,1+i)}'

Q4

以下のデータについて、「すっとこどっこい」を「朴念仁」に変換しましょう。「すっとこどっこい」以外の部分の改行は除去してはいけません。

$ cat Q4 
   この
   すっとこどっ
   こい
   すこっと
   どっこい
   すっとこすっとこど
   っこい
   どっこいどっこい
   すっとこどっこん
   すっ
   とこ
   どっ
   こい

解答

$ cat Q4 | tr '\\n' @ |
   sed 's/す@*っ@*と@*こ@*ど@*っ@*こ@*い/朴念仁/g' | tr @ '\\n' | awk '{print}'
   この
   朴念仁
   すこっと
   どっこい
   すっとこ朴念仁
   どっこいどっこい
   すっとこどっこん
   朴念仁

Q5

/?page_id=7123 から、画像を抜き出して保存しましょう。

解答

$ curl https://blog.ueda.asia/?page_id=7123 |
    grep -o '<img src="data:[^>]*/>' | sed 's/^.*,//' |
    sed 's;"/>$;;' | base64 -d > chinjyu.png

Q6

ファイルQ6は、Shift JISで記録された日本語を2進数にしたものです。ワンライナーで日本語に直してみましょう。

$ cat Q6
   1000101001100101100100100110111010000010110010011001000110111101100011101110110110010001101111011001011101101100100000101100100010010011011100011001010010001110100000101010101010010001101101101000110111011101100000101011011110000010111010011000000101000010000011010000101010010011110000011000001011001001100101110100110010010110101111001000001011001000100000101110000010000010110011001000001011001101100101101110110010001011100001011001001101110001100101001000111010000010110001011000001010100000100000101110100110000001010000100000110100001010

解答

一例です。

$ echo -n "obase=16;ibase=2;" | cat - Q6 | sed 's/$/;\\n/' |
    bc | tr -d '\\\\\\n' | xxd -r -ps | nkf
   各地に多種多様な賭博が存在する。
   特に有名なものは野球賭博である。

Q7

bashでは変数SHLVLに、今使っているbashの深さ(子シェル:2, 孫シェル:3, ...)が入っています。echo $SHLVLで、100を出してみてください。

解答

自身を呼び出すシェルスクリプトを使って実行するのが一つの方法です。

$ echo 'echo $SHLVL && [ $SHLVL -lt 100 ] && ./a' > a ; chmod +x a ; ./a
   ###@papironさんの答え###
   $ yes 'bash' | head -n 98 | (cat; echo 'echo $SHLVL') | bash

Q8

以下のワンライナーに加筆して、1000プロセスぐらい立ち上げた後で止めてみてください。壊しても良い環境で行ってください。

$ : (){ : | : & }; :

解答

変数を起動するたびにファイルに1行追記してやって条件を判定すれば、安心してください。止まりますよ。(失敗すると止まらないけど。)

###wc -l < aをwc -l aとすると止まらないので注意###
   $ : (){ echo a >> a ; [ "$(wc -l < a)" -gt 1000 ] && exit 0; : | : & }; :
ノート   このエントリーをはてなブックマークに追加 
 

prev:【問題】第19回シェル芸3周年記念勉強会 next:考えたくない人向けWiringPi2導入手順(Raspberry Pi2 Model B, 2015年11月6日現在)

やり散らかし一覧

記事いろいろ