■USP友の会 20130622第5回シェル芸勉強を解いてみた。
20130622第5回シェル芸勉強会スライド
http://www.slideshare.net/ryuichiueda/20130622-23348634
問題1
・あるディレクトリで適当にファイルへのシンボリックリンクを作り、
リンク先のファイルをコピーして実体のあるファイルに置き換えてください。
■シンボリックは「-h」で判定、「cp -b」でバックアップオプションを指定。
$ ln -s /var/log/syslog syslog; \
ln -s /var/log/syslog.1 syslog.1
$ ls -l | sed s/`whoami`/"sample"/g
合計 0
lrwxrwxrwx 1 sample sample 15 10月 14 21:42 syslog -> /var/log/syslog
lrwxrwxrwx 1 sample sample 17 10月 14 21:42 syslog.1 -> /var/log/syslog.1
$ for list in *;do test -h "$list" && sudo cp -b `readlink -f $list` $list;done
$ ls -l | sed s/"`whoami`\|root"/"sample"/g
合計 288
-rw-r----- 1 sample sample 15182 10月 14 21:50 syslog
-rw-r----- 1 sample sample 274641 10月 14 21:50 syslog.1
lrwxrwxrwx 1 sample sample 17 10月 14 21:49 syslog.1~ -> /var/log/syslog.1
lrwxrwxrwx 1 sample sample 15 10月 14 21:49 syslog~ -> /var/log/syslog
問題2
・/etc/hostsと/etc/resolv.confをつなげて、以下のように各行に元のファイル名が
ついた一つのファイルを作ってください。
/etc/hosts
/etc/hosts
/etc/hosts
(略)
/etc/resolv.conf
/etc/resolv.conf
/etc/resolv.conf
(略)
■サンプルから。
$ grep . switchconf/examples/home/etc/{hosts,resolv.conf} | \
sed s%"switchconf/examples/home"%%g | tr ':' ' '
/etc/hosts 127.0.0.1 localhost
/etc/hosts 192.168.0.16 myhost.myhome.org myhost
/etc/resolv.conf search myhome.org
/etc/resolv.conf nameserver 192.168.0.254
問題3
・問題2で作ったファイルを適当なディレクトリの下に復元してください。
■ノーマルに。
$ for list in hosts resolv.conf;do \
COUNT=`echo "/etc/$list " | wc -c` ; \
grep "$list" sample | cut -c ${COUNT}- >> "$list"; \
done
$ grep . hosts resolv.conf | tr ':' ' '
hosts 127.0.0.1 localhost
hosts 192.168.0.16 myhost.myhome.org myhost
resolv.conf search myhome.org
resolv.conf nameserver 192.168.0.254
問題4
・a,bそれぞれについて一番下にある行を取り出してください。
$ cat data2
a 14
a 5
b 12
b 3
a 20
b 1
b 2
■2種類しかないので。
$ awk '{if($1=="a"){a=$0}else{b=$0}};END{print a"\n"b}' data2
a 20
b 2
問題5
・下の図のように魔方陣を作って、
魔方陣になっているかどうか確認してください。
■縦横の合計すべてが等しい数の行列の計ならOK。
$ echo $(sed s/" "/"+"/g data1 | bc;awk '{a+=$1;b+=$2;c+=$3};END{print a,b,c}' data1) | \
sed s/" "/"\n"/g | uniq -c | awk '($1==6){print "魔方陣"}'
魔方陣
問題6
・/usr/share/dict/words 等辞書から大文字で始まる単語、
小文字で始まる単語の数を数えてください。
■セミコロンで区切っても区切らなくても。
$ echo -n "小文字で始まる単語の数:";grep ^[a-z] /usr/share/dict/words | wc -l; \
echo -n "大文字で始まる単語の数:";grep ^[A-Z] /usr/share/dict/words | wc -l;
小文字で始まる単語の数:82671
大文字で始まる単語の数:16483
$ echo `grep ^[a-z] /usr/share/dict/words | wc -l` `grep ^[A-Z] /usr/share/dict/words | wc -l`
82671 16483
問題7
$ echo ダァシェリイェス
して、ワンライナーで時を斑点してください。
(「ダ」がめんどくさい)
■nkf使ってもいいし、使わなくてもいい。
$ echo ダァシェリイェス | nkf | sed s/./"&\n"/g | tac | xargs echo -n | tr -d ' ' | nkf -Z4;echo
スェイリェシァダ
$ echo ダァシェリイェス | sed s/"ダ"/"ダ"/ | sed s/./"&\n"/g | tac | xargs echo -n | tr -d ' ' | sed s/"ダ"/"ダ"/;echo
スェイリェシァダ
問題8
・以下のような図形を出力してください。
a
aaa
aaaaa
aaaaaaa
aaaaa
aaa
a
■わかりやすく。
$ echo $(echo "<div align=center>"; \
for n in 1 3 5 7 5 3 1;do \
echo `seq 1 $n` | sed s/[0-9]/a/g | tr -d ' ';echo "<br/>"; \
done;echo "</div>") | \
w3m -dump -T text/html -cols 10
a
aaa
aaaaa
aaaaaaa
aaaaa
aaa
a
問題9
・右図のように縦に1つずつランダムにずらして字を出力してください。
$ echo 15 | awk '{a=10;for(i=1;i<=$1;i++){a=a+(rand()>0.5?-1:1);print a}}' | \
awk '{for(i=1;i<=$1;i++){printf " "}{printf "o\n"}}'
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
■右か左かに限定した場合
$ seq 0 9 | sort -R | \
for n in `xargs`;do echo $n | awk '{if($n%2==0){print " o"}else{print "o "}}';done
o
o
o
o
o
o
o
o
o
o
■「%3」だとひとつ飛びになることがある。
$ seq 0 11 | sort -R | \
awk '{print $1%2}' | \
for n in `xargs`;do \
for m in `seq 0 11`;do \
if [ $m -eq $(($n+10)) ];then echo "o";break;else echo -n " ";fi; \
done; \
done
o
o
o
o
o
o
o
o
o
o
o
o
問題10
・/usr/share/dict/words から中手流した単語で、
this is a pen
という出力を得てください。
ーただし、数字は一切使わないこと
ーシェル変数、ファイルにも出力しないこと
ーfor,while,&&禁止
■数字を使う方法
$ grep "^this\$\|^is\$\|^a\$" /usr/share/dict/words | xargs echo -n | \
sed s/"\(.\) \(..\) \(...\) \(....\)"/"\4 \2 \1 \3"/;echo
this is a pen
■解答例をヒントに強引に順番を作る方法
$ sed s/"^this\$"/"_&"/ /uwords | sed s/"^is\$"/"__&"/ | \
sed s/"^a\$"/"___&"/ | sed s/"^pen\$"/"____&"/ | \
grep "^_" | sort -r | tr -d "_" | tr '\n' ' ';echo
this is a pen