【問題と解答】jus共催 第32回全くインスタ映えしないシェル芸勉強会
Sat Dec 2 16:47:03 JST 2017 (modified: Sun Dec 3 17:46:19 JST 2017)
views: 12925, keywords:プログラミング,勉強会,シェル芸,シェル芸勉強会 この記事は最終更新日が6年以上前のものです。
- 問題のみのページはこちら
- 問題で使われているデータファイルはGitHubにあります。クローンは以下のようにお願いします。
git clone https://github.com/ryuichiueda/ShellGeiData.git $
- 環境: 解答例はUbuntu Linux 16.04 で作成。Macの場合はcoreutilsをインストールすると、GNUのコマンドが使えます。BSD系の人は玄人なので各自対応のこと。
Q1
つぎのように1から9までの数を、間の数字を適当抜いてechoで出力します。
echo 14679
このechoの後ろにパイプでコマンドをつなぎ、次のように各数字を1行一個、抜けた数字の行を飛ばして出力してください。
1
4
6
7
9
解答
echo 14679 | sed 's/./&\n/g' | awk '{a[$1]=$1}END{for(i=1;i<=9;i++)print a[i]}'
$ 1
4
6
7
9
Q2
Q1と同じ入力から始めて、今度は
1
a
b
4
c
6
7
d
9
というように、間をa,b,c,...と埋めてください。
解答
echo 14679 | sed 's/./&\n/g' |
$ awk '{a[$1]=$1}END{for(i=1;i<=9;i++)print a[i]}' |
awk 'BEGIN{n=1}FILENAME~/fd/{a[NR]=$1}
FILENAME=="-"{if(NF==0){print a[n++]}else{print}}' <(echo {a..z} | tr ' ' '\n') -
1
a
b
4
c
6
7
d
9
Q3
/etc/services
から、TCPのポート番号が素数のサービス一覧を作ってください。
解答
cat /etc/services | awk '$2~/\/tcp$/' | awk -F/ '{print $1}' |
$ while read s p; do echo $s $(factor $p) ; done |
awk 'NF==3{print $1}' | xargs
echo systat daytime qotd chargen telnet time whois domain bootps finger hostnames rtelnet pop2 auth netbios-ns netbios-ssn cmip-man bgp prospero smux fatserv ldap https saft nqs ipp dhcpv6-server nntps submission proofd ms-sql-s remctl mtn x11-7 afs3-callback bacula-sd bpdbm wnn6 kerberos-master kpop knetd kx cfinger enbd-cstatd tproxy isdnlog
Q4
次のデータを
136
725 948
次のように並べ替えてください。
9
7
4
1
2
8
3
5
6
解答
tac nums.txt | sed 's/./& /g' | awk '{for(i=1;i<=NF;i++){print $i,i+NR,i}}' |
$ sort -k2,3 | awk '{print $1}'
9
7
4
1
2
8
3
5
6
Q5
ウムラウトを含む単語だけ抽出してください。ワンライナー中にウムラウトを使用しないでください。
wäschst wash 山田x Schrödinger
y上田 Ö アイウエオ unko Übel Ärztin hoge カキクケコ
解答
tr ' ' '\n' < umlaut.txt | sed 's/./& /g' |
$ LANG=C awk '{for(i=1;i<=NF;i++){ln=length($i);if(ln==3){next}}print}' |
tr -d ' ' | LANG=C /bin/grep '[^[:alpha:]]'
wäschst
Schrödinger
Öbel
Ürztin Ä
Q6
ツイッターの特定のアカウントについて、つぶやきがあるたびに「んほぉ!」と端末に表示するワンライナーを書いてください。
解答
while sleep 3 ; do w3m https://twitter.com/minyoruminyon -dump |
grep ツイートツイート | tr -dc 0-9 | xargs ; done | awk 'a!=$1&&NR>1{print "んほぉ!"}{a=$1}'
Q7
次のファイルについて、次の処理をやってください。
- ある数字について、上下左右の数字どれか1つに0が含まれる場合は0、そうでなければ1にする。
- 次に、上下左右の数字どれか1つに1が含まれる場合は1、そうでなければ0にする。
cat image.txt
$ 00010000000000001000000
00000000111111111110000
01111110011111111110001
00011110001111111111000
10011110001111111111000
00000001000000001000000
正解の出力を示します。
00000000000000001000000
00000000001111111100000
00001100011111111110000
00011110001111111111000
00001100000111111110000
00000000000000001000000
解答
cat image.txt | sed 's/./& /g' |
$ awk '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(j=1;j<=NR;j++)
{for(i=1;i<=NF;i++){printf(a[j-1,i]+a[j+1,i]+a[j,i-1]+a[j,i+1])" "}
print ""}}' | tr 1234 0001 |
awk '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(j=1;j<=NR;j++)
{for(i=1;i<=NF;i++){printf(a[j-1,i]+a[j+1,i]+a[j,i-1]+a[j,i+1])}
print ""}}' | tr 1234 1111
Q8
次のようなテキストについて、漢字やカタカナが行頭に来るように改行を入れるワンライナーを考えてください。ただし、「シェル芸」のようにカタカナ+漢字のものは1単語として扱い、改行を入れないでください。この問題については一般解を考えてみましょう。
cat japanese.txt
$
ん僕らは既に死んでいる 死んでいるからシェル芸だ。
出力を示します。最初の「ん」は独立した行に出力してください。
ん
僕らは
既に
死んでいる
死んでいるから
シェル芸だ。
解答
cat japanese.txt |
$ grep -Po '([^\p{Han}\p{Katakana}]+|[^\p{Han}\p{Katakana}]*[\p{Katakana}\p{Han}]+[^\p{Han}\p{Katakana}]+)'
ん
僕らは
既に
死んでいる
死んでいるから シェル芸だ。