■第15回ドキッ!grepだらけのシェル芸勉強会 を解いてみた。
シェル芸勉強会の自分の回答一覧(第1回~第13回)
http://labunix.hateblo.jp/entry/20150316/1426433547
シェル芸勉強会スライド一覧
http://blog.ueda.asia/?page_id=684
第14回東京居残りシェル芸勉強会を解いてみた。
http://labunix.hateblo.jp/entry/20150322/1426951657
(番外編)2015年お正月用問題 を解いてみた。
http://labunix.hateblo.jp/entry/20150322/1427007182
■Q1.次のようにファイルを作ります。
1という文字を含まないファイルを列挙してください(aとdですね)。
$ seq 2 5 > a;seq 1 9 > b;seq 5 11 > c;seq 3 6 > d
$ grep -L 1 [a-d]
a
d
$ for n in {a..d};do grep 1 "$n" >/dev/null || echo $n;done
a
d
■Q2.作業ディレクトリを作り、その下に次のようにfile.1〜file.10000という
ファイルを作ります。
以下の数字を持つファイルだけ残して後のファイルを消去してください。
1〜9
10, 20, 30, …, 90
数字の下2桁が0のファイル
$ mkdir work && cd work;seq 1 10000 | xargs -I@ touch file.@
■確認もしないで消すのは無しかな。。。
$ ls -f file* | grep "file.[1-9]\$\|file.[1-9]0\$\|file.*00\$" | \
tr '\n' ' ' | sed s/"\(file.[0-9]* \)\{8\}"/"&\n"/g;echo
file.1 file.10 file.100 file.1000 file.10000 file.1100 file.1200 file.1300
file.1400 file.1500 file.1600 file.1700 file.1800 file.1900 file.2 file.20
file.200 file.2000 file.2100 file.2200 file.2300 file.2400 file.2500 file.2600
file.2700 file.2800 file.2900 file.3 file.30 file.300 file.3000 file.3100
file.3200 file.3300 file.3400 file.3500 file.3600 file.3700 file.3800 file.3900
file.4 file.40 file.400 file.4000 file.4100 file.4200 file.4300 file.4400
file.4500 file.4600 file.4700 file.4800 file.4900 file.5 file.50 file.500
file.5000 file.5100 file.5200 file.5300 file.5400 file.5500 file.5600 file.5700
file.5800 file.5900 file.6 file.60 file.600 file.6000 file.6100 file.6200
file.6300 file.6400 file.6500 file.6600 file.6700 file.6800 file.6900 file.7
file.70 file.700 file.7000 file.7100 file.7200 file.7300 file.7400 file.7500
file.7600 file.7700 file.7800 file.7900 file.8 file.80 file.800 file.8000
file.8100 file.8200 file.8300 file.8400 file.8500 file.8600 file.8700 file.8800
file.8900 file.9 file.90 file.900 file.9000 file.9100 file.9200 file.9300
file.9400 file.9500 file.9600 file.9700 file.9800 file.9900
$ ls -f ../file* | grep "file.[1-9]\$\|file.[1-9]0\$\|file.*00\$" | \
awk '{print "mv "$1" ."}' | sh
$ rm ../file.* && mv file.* ../ && cd ../ && rmdir tmp
■Q3.次のテキストから、「-v」、「-f」、「awk」の数をそれぞれカウントしてください。
gawk、nawkは避けてください(awkの数としてカウントしない)。
できる人はgrepは1個で。さらにできる人は拡張正規表現を使わないでやってみましょう。
$ cat text1
awk -v v="hoge" 'BEGIN{print v}'
echo 'BEGIN{print 1}' | gawk -f -
nawk 'BEGIN{print " BEGIN{print x}"}' | awk -v x=3 -f -
$ grep -o "\-[fv]\|^awk\| awk" text1 | tr -d ' ' | sort | uniq -c
2 -f
2 -v
2 awk
■Q4./etc/の下(子、孫、・・・)のファイルのうち、シバンが「#!/bin/sh」のシェルスクリプトについて、
中に「set -e」と記述のあるファイルとないファイルの数をそれぞれ数えてください。
(コメント中のset -eも数えてOKです。)
$ sudo find -type f | sudo grep -l '#!/bin/sh' /etc/ -R 2>/dev/null | \
sudo xargs grep -c 'set -e' | \
awk -F\: '{if($2>0){ysum+=1}else{nsum+=1}};END{print "zero",nsum"\nnon zero",ysum}'
zero 304
non zero 81
■Q5.日本語やギリシャ文字のある行を除去してください。
$ cat text2
A pen is a pen?
日本語でおk
ΩΩπ<Ω< na nandatte!!
Randy W. Bass
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
■今回は最初の文字で区別できます。
$ LANG=C grep "^[[:print:]]*$" text2
A pen is a pen?
Randy W. Bass
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
$ awk '/^[A-z0-9]/{print}' text2
A pen is a pen?
Randy W. Bass
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
■次のようにファイルa, b, cを作ります。
$ echo 1 2 3 4 > a;echo 2 3 4 5 > b;echo 1 4 5 > c
ファイルの中の数字を足して10になるファイルを挙げてください。
$ for n in {a..c};do cat $n | tr ' ' '\n' | awk 'sum+=$1;END{print sum}' | \
grep ^10 >/dev/null && echo $n;done
a
c
■Q7.psコマンドを打って(オプションは任意)、
そのpsコマンドの行、親プロセスの行、親の親のプロセスの行を表示してみてください。
■親プロセスIDで再検索するだけ。
$ ps T -o ppid,pid,cmd `ps T -o ppid,pid,cmd | awk '/^ [0-9]/ {print $1}'`
PPID PID CMD
4303 9240 gnome-terminal
9240 9247 bash
9247 10615 ps T -o ppid,pid,cmd 9240 9247
■Q8.seqとfactorの出力の後ろにgrepだけをいくつかつなげて、「素数の一つ前の数で、かつ10以上の数」を列挙してください。
■素数の一つ前で、素数ではない数が自動的に10以上なのでそのまま列挙。
※最初の素数は11なので。
$ seq 10 1000 | factor | grep -B 1 "[0-9]*\: [0-9]*\$" | \
grep "[0-9]*\: [0-9]* [0-9]*" | grep -o ^[0-9]* | column
10 78 166 262 366 462 586 682 810 928
12 82 172 268 372 466 592 690 820 936
16 88 178 270 378 478 598 700 822 940
18 96 180 276 382 486 600 708 826 946
22 100 190 280 388 490 606 718 828 952
28 102 192 282 396 498 612 726 838 966
30 106 196 292 400 502 616 732 852 970
36 108 198 306 408 508 618 738 856 976
40 112 210 310 418 520 630 742 858 982
42 126 222 312 420 522 640 750 862 990
46 130 226 316 430 540 642 756 876 996
52 136 228 330 432 546 646 760 880
58 138 232 336 438 556 652 768 882
60 148 238 346 442 562 658 772 886
66 150 240 348 448 568 660 786 906
70 156 250 352 456 570 672 796 910
72 162 256 358 460 576 676 808 918