【問題と解答】第20回記念、年末年始の浮ついた気分大粉砕シェル芸勉強会

Sat Dec 26 16:49:18 JST 2015 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 3678, keywords:CLI,UNIX/Linuxサーバ,USP友の会,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が7年以上前のものです。

問題だけページはコチラ

イントロ

第20回シェル芸勉強会イントロ from 隆一 上田

問題で使うファイル等

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

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

にあります。

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

$ 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

リポジトリ内のvol.20/Q1ディレクトリには次のように数字が書いてあるファイルが4つ入っています。

$ ls 
   file_A-1 file_A-2 file_B-1 file_B-2
   $ head -n 2 *
   ==> file_A-1 <==
   1
   31351
   
   ==> file_A-2 <==
   11
   35
   
   ==> file_B-1 <==
   -32
   12
   
   ==> file_B-2 <==
   912
   3

file_A-のグループ、file_B-のグループからそれぞれ最大の数を探してください。他にfile_C-、file_D-、・・・とグループがたくさんあると想定して、1回のワンライナーで両方探すこととします。

解答

$ grep ^ * | sed 's/-[0-9]*:/ /' | sort -k1,1 -k2,2nr |
   awk '{print $2,$1}' | uniq -f 1
   233333 file_A
   9912 file_B

Q2

アンサイクロぺディアのシェル芸のページから、「カースト最上位者が日常的に書く、素数を出力するワンライナー」のコードを取得して実行してください。

解答

$ curl -s http://ja.uncyclopedia.info/wiki/%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8 |
   grep eval | sed 's/^..//' | bash

Q3

次のファイルについて、奇数を1列目、偶数を2列目に振り分けて、奇数の列を昇順、偶数の列を降順にソートしてください。

$ cat Q3
   1
   4
   2
   9
   5
   8

つまりこうしてください。

1 8
   5 4
   9 2

解答

$ paste <(awk '$1%2' Q3 | sort) <(awk '$1%2==0' Q3 | sort -r) | tr '\\t' ' '
   1 8
   5 4
   9 2
   $ cat Q3 | sed 's/.*[02468]$/-&/' | sort | xargs |
   awk '{for(i=NF/2;i>=1;i--){print $(NF-i+1),-$i}}'
   1 8
   5 4
   9 2

Q4

今、ログインしているサーバについて、自分の今使っているリモート端末以外の端末を抹殺してください。rootになっても構いません。

解答

もっと楽な方法がありそうですが・・・。ttyコマンドはオプションに$()で埋め込んでもうまく働きません。(ttyが端末と関係ないプロセスで立ち上がるので)。

ueda@remote:~$ a=$(tty | sed 's;/dev/;;') ; ps aux |
   awk '$7~/pts\\/[0-9]*/' | awk -v "t=$a" '$7!=t' |
   awk '{print $2}' | xargs sudo kill 

Q5

任意の二つの自然数をechoして最大公約数を求めましょう。

解答

ueda@remote:~$ echo 45 126 |
   awk '{while($1*$2!=0){if($1>$2){$1=$1-$2}else{$2=$2-$1}print}}' |
   awk 'END{print $1}'
   9
   ###Tukubai使用(こっちの方が長いが・・・)###
   ueda@remote:~$ echo 60 9 | factor | tarr num=1 | tr -d : | 
   self 2 1 | sort | count 1 2 | self 1 3 | yarr num=1 |
   awk 'NF>2' | awk '{print $1,$2<$3?$2:$3}' |
   awk 'BEGIN{a=1}{a*=$1**$2}END{print a}'

Q6

ファイルQ6の中の人の名前について、誰が1列目と2列目の何番めに記述されているかを求めましょう。

###スペースは全角###
   $ cat Q6
   山田 上田 吉田 武田
   吉田 武田 上田 山田

解答例は次のようなものです。

吉田 3 1
   山田 1 4
   上田 2 3
   武田 4 2

解答

$ cat Q6 | sed 's/ / /g' | awk '{for(i=1;i<=NF;i++){print $i,NR,i}}' |
   sort -k1,2 | awk '{print $1,$3}' | xargs -n 4 | awk '{print $1,$2,$4}'
   吉田 3 1
   山田 1 4
   上田 2 3
   武田 4 2

Q7

一部分に「魚」を持つ漢字をなるべくたくさん列挙してみてください。方法はお任せします。

解答

あくまで一例で一部分ですが・・・

$ seq 39770 40058 | xargs printf "&#x%x;" | nkf --numchar-input 

Q8

次の漢数字をアラビア数字に変換しましょう。

$ cat Q8 
   五千七百三十五
   四千三
   四十五
   九万六千二百三十三
   十一
   百十二

解答

$ cat Q8 | sed 'y/一二三四五六七八九/123456789/' |
   nkf -Z1 | sed 's/十/1*10+/' | sed 's/百/1*100+/' |
   sed 's/千/1*1000+/' | sed 's/万/1*10000+/' |
   sed 's/\\([0-9]\\)1/\\1/g' | bc
   5735
   4003
   45
   96233
   11
   112

宣伝

[amazonjs asin="4774173444" locale="JP" title="シェルプログラミング実用テクニック (Software Design plus)"]

ノート   このエントリーをはてなブックマークに追加 
 

prev:【問題のみ】第20回記念、年末年始の浮ついた気分大粉砕シェル芸勉強会 next:新春エクストリームシェル芸大会

やり散らかし一覧

記事いろいろ