【問題と解答】第29回激しいシェル芸勉強会

Pocket
LINEで送る

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

問題で使うファイル等

GitHubにあります。ファイルは

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

にあります。

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

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

環境

解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールの上、gsedをつかいましょう。BSD系の人は玄人なので各自対応のこと。

イントロ

Q1

次の2つのファイルは、講義で出した課題1,2それぞれの点数です。

$ cat kadai1
001 山田 20
002 出川 30
005 鳥海 44
$ cat kadai2 
001 山田 20
003 上田 15
004 今泉 22
005 鳥海 44

両方に名前のある人については点数を合計して、次のように全員の得点リストを作ってください。

001 山田 40
002 出川 30
003 上田 15
004 今泉 22
005 鳥海 88

解答

$ join -a 1 -a 2 -1 1 -2 1 kadai{1,2} | awk '{print $1,$2,$3+$5}'
001 山田 40
002 出川 30
003 上田 15
004 今泉 22
005 鳥海 88

Q2

次の2つのファイルは、5回の講義の出欠と6回目の講義で出席した人の番号のデータです。attendに6回目の講義の出欠を反映したデータを標準出力に出力してください。

$ cat attend
001 山田 出出欠出出
002 出川 出出欠欠欠
003 上田 出出出出出
004 今泉 出出出出出
005 鳥海 欠出欠出欠
$ cat attend6
001,005,003

解答

$ tr , '\n' < attend6 | sort | sed 's/$/ 出/' |
 join -a 1 attend - |
 awk 'NF==3{print $0"欠"}NF==4{print $1,$2,$3$4}'

Q3

次の2つのファイルは5回の講義の出欠とテストの成績を記録したファイルです。

###$1: 番号, $2: 名前, $3: 出欠 ###
$ cat attend 
001 山田 出出欠出出 
002 出川 出出欠欠欠
003 上田 出出出出出
004 今泉 出出出出出
005 鳥海 欠出欠出欠
###$1: 番号, $2: テストの点数(受けてない人のデータは無い)###
$ cat test 
001 90
002 78
004 80
005 93

こういうルールで、最終的な点数を出して、番号、名前、点数を記録したファイル作ってください。

  • 出席が過半数に満たない人、テストを受けていない人は0点
  • 出席が過半数の人はテストの点数を採用

解答

$ join -a 1 -o 1.1 1.2 1.3 2.2 -e 0 attend test |
 awk '/(.*欠){3}/{$4=0}{print}'
001 山田 出出欠出出 90
002 出川 出出欠欠欠 0
003 上田 出出出出出 0
004 今泉 出出出出出 80
005 鳥海 欠出欠出欠 0

Q4

Q4.1

次の出力をパイプで受けて

$ echo -1 4 5 2 42 421 44 311 -9 -11

次のように同じ桁のものを横並びに出力を得てください。横に並べる時の順番は任意とします。また、この出力のように正の数と負の数を分けます。

-11 
-9 -1 
2 4 5 
42 44 
311 421 

Q4.2

次の出力をパイプで受けて

$ echo -1 +4 5 2 42 421 44 311 -9 -11

次のように同じ桁のものを横並びに出力を得てください。Q1.1と同じく横に並べる時の順番は任意とします。

-11 
-9 -1 
2 +4 5 
42 44 
311 421 

解答

Q4.1

$ echo -1 4 5 2 42 421 44 311 -9 -11 | xargs -n 1 | sort -n |
 awk 'length(a) != length($1){print ""}{printf("%d ",$1);a=$1}' |
 awk 'NF'
-11 
-9 -1 
2 4 5 
42 44 
311 421 

Q4.2

awk内で1をかけると+符号が外れるので、符号を外して桁数を比較すると先ほどの解答例が転用できます。

$ echo -1 +4 5 2 42 421 44 311 -9 -11 | xargs -n 1 | sort -n |
 awk 'length(a*1) != length($1*1){print ""}{printf("%s ",$1);a=$1}' |
 awk 'NF'
-11 
-9 -1 
+4 2 5 
42 44 
311 421 

Q5

次のファイルの中身について、

$ cat triangle 
   1
  3 9
 7 a 6
8 4 2 5

次のように右に転がしてください。できる人はawkを使わないでやってみましょう。

   8   
  4 7  
 2 a 3 
5 6 9 1

解答

四角にして回すと楽です。

$ cat triangle | sed 's/ /0 /g' | sed 's/\([^ ]\)0/\1/g' |
 tac | rs -T | tr -d 0 | sed 's/  / /g' | sed '1s/^/   /' |
 sed '2s/^/  /'  | sed '3s/^/ /'
   8   
  4 7  
 2 a 3 
5 6 9 1

Q6

次の1から100までの素数を書いたファイル(いくつか欠番が存在)について、

$ cat prime 
2 3 5 7 11 13 17 19 31 37 41 43 47 53 59 67 71 73 79 83 89 97

次のように欠番のところで折り返してください。(ワンライナーの中に欠番を直接書かないでくださいね。)

2 3 5 7 11 13 17 19 
31 37 41 43 47 53 59 
67 71 73 79 83 89 97

解答

$ cat prime | xargs -n 1 | cat - <(seq 1 100 | factor |
 awk 'NF==2{print $2}') | sort -n | xargs |
 awk '{for(i=1;i<NF;i+=2){if($i==$(i+1)){printf("%d ",$i)}else{print "";i-=1}}}' |
 awk 'NF'
2 3 5 7 11 13 17 19 
31 37 41 43 47 53 59 
67 71 73 79 83 89 97 

Q7

リポジトリ内のnyaan.htmlは、ブラウザで見ると次のように見えます。

次のようにcatから始めて、この文字を(大きなまま)端末上に表示してみてください。

$ cat ./nyaan.html | ...

できる人は小さい通常の文字で「にゃーん」と出してみてください(これは解答例を考えていません)。

解答

$ cat ./nyaan.html | nkf --numchar-input |
 sed 's/<[^<]*>//g' | sed 's/&quot;/"/g'

Q8

次のshellgeiファイルについて、

$ cat shellgei 
                                            m                         
   ""m                        m  "m          #    # #           #     
  mm                           #  #          #mmm"""          m"      
    "    m"      mmm""         #  #   #     m"   #        mm""m       
       m"          #mm        m"  # m"     "    #             #       
  "mm""         """"  "      m"   #"          m"              #       
                                                                      
                   

次のように、文字の無い列を詰めてください。

                          m               
 ""m             m "m      #    # #      #
mm                # #      #mmm"""     m" 
  "    m" mmm""   # #   # m"   #   mm""m  
     m"     #mm  m" # m" "    #        #  
"mm""    """"  "m"  #"      m"         #                                     

解答

$ cat shellgei | sed 's/ /@/g' | sed 's/./& /g' |
 awk '{for(i=1;i<=NF;i++){if($i!="@")a[i]=$i}}END{for(i=1;i<=NF;i++){b=a[i]==""?"x":" ";printf b}}END{print ""}' |
 cat - shellgei |
 awk 'NR==1{a=$0}{for(i=1;i<=length($0);i++){if(substr(a,i,1)!="x")printf substr($0,i,1)};print ""}'
                                          
                          m               
 ""m             m "m      #    # #      #
mm                # #      #mmm"""     m" 
  "    m" mmm""   # #   # m"   #   mm""m  
     m"     #mm  m" # m" "    #        #  
"mm""    """"  "m"  #"      m"         #  
                                          
                      

もっと良い解答。

Pocket
LINEで送る

「【問題と解答】第29回激しいシェル芸勉強会」への1件のフィードバック

コメントは停止中です。