■第9回寒中シェル芸勉強会を解いてみた。
シェル芸勉強会スライド一覧
http://blog.ueda.asia/?page_id=684
第1問
まず、次のようにファイルを作ってください。
$ touch apple avocado banana cinnamon melon
$ ls
apple avocado banana cinnamon melon
「a,b,c,m」というディレクトリを作って、1文字目が対応するファイルを
それぞれのディレクトリに移動してください。
■普通に解く。
$ mkdir {a,b,c,m} ; \
find . -type f | awk '{print "mv",$1,$1}' | sed s%./%%g | \
sed s/" \([a-z]\)[a-z]*\$"/" \1"/ | sh
$ tree
.
├── a
│ ├── apple
│ └── avocado
├── b
│ └── banana
├── c
│ └── cinnamon
└── m
└── melon
4 directories, 5 files
第2問
まず、次のように名前にスペースが入ったファイルを作ります。
$ touch "私は 蟹" "オシャレな 蟹" "足が 10本"
$ ls -l
total 0
-rw-r--r-- 1 ueda staff 0 2 14 11:22 私は 蟹
-rw-r--r-- 1 ueda staff 0 2 14 11:22 足が 10本
-rw-r--r-- 1 ueda staff 0 2 14 11:22 オシャレな 蟹
このままでは何かと扱いづらいので、間にアンダーバーを入れて
次のように名前を変更してください。
$ ls -l
total 0
-rw-r--r-- 1 ueda staff 0 2 14 11:25 私は_蟹
-rw-r--r-- 1 ueda staff 0 2 14 11:25 足が_10本
-rw-r--r-- 1 ueda staff 0 2 14 11:25 オシャレな_蟹
■ノーマルな手段で。
$ touch "私は 蟹" "オシャレな 蟹" "足が 10本"; \
ls -l *" "* | cut -c 47- | grep -v ^\$ | \
while read line;do \
mv "$line" "`echo "$line" | sed s/" "/"_"/g`"; \
done
第3問
ディレクトリを適当に作って、20140101から20141231まで、
日付に対応したファイルを作って下さい。
各ファイルの中には各日付に対応するdateコマンドの出力を書き込んで下さい。
■12度やるか、変数に入れるか。それが問題だ。
$ test -d daylist || mkdir daylist && cd daylist; \
seq 20140101 20141231 | \
for n in `xargs`;do \
date -d "$n" > /dev/null 2>&1 && date -d "$n" | tee $n >/dev/null 2>&1; \
done
$ ls | wc -l
365
$ grep . 2014* | head -5
20140101:2014年 1月 1日 水曜日 00:00:00 JST
20140102:2014年 1月 2日 木曜日 00:00:00 JST
20140103:2014年 1月 3日 金曜日 00:00:00 JST
20140104:2014年 1月 4日 土曜日 00:00:00 JST
20140105:2014年 1月 5日 日曜日 00:00:00 JST
第4問
次のように4個ファイルを作って、a_ramenとa_curry、b_appleとb_tomatoの
ファイルの中身を入れ替えてください。
$ echo カレー > a_ramen
$ echo ラーメン > a_curry
$ echo トマト > b_apple
$ echo リンゴ > b_tomato
■面倒の一言。
$ grep . [ab]*
a_curry:ラーメン
a_ramen:カレー
b_apple:トマト
b_tomato:リンゴ
$ grep . [ab]* | tr "\n\|:" " " | \
awk '{;print $4,$1"\n"$2,$3"\n"$8,$5"\n"$6,$7}' | \
sed s/" "/" > "/g | sed s/^/"echo "/g | sh
$ grep . [ab]*
a_curry:カレー
a_ramen:ラーメン
b_apple:リンゴ
b_tomato:トマト
第4問
各月ごとにtar.gzファイルにしてください。
$ ls *[0-9] | cut -c 1-6 | sort -u | \
for list in `xargs`;do tar zcvf ${list}.tar.gz $list*;done
$ for list in *.tar.gz;do tar ztvf $list;done | awk '{print $NF}' | wc -l
365
第6問
次のようなディレクトリ・ファイルを作って下さい。
~/a/a/a/.../a/a/b (aが百個、bはファイル)
■作成ついでにシェル芸で確認
$ for n in `seq 1 100`;do echo -n "a/";done | \
awk '{print "mkdir -p",$1,"\ntouch",$1"b"}' | sh
$ find . -type f -name b | tr '/' '\n' | grep a | wc -l
100
第7問
先ほど作ったファイルbを、50番目のaディレクトリに移動して下さい。
■上に同じ。
$ find . -type f -name b | \
echo "mv `xargs` $(for n in `seq 1 50`;do echo -n "a/";done)" | sh
$ find . -type f -name b | tr '/' '\n' | grep a | wc -l
50
第8問
先ほど作ったディレクトリについて rm -r を使わずに~/a 以下のディレクトリを消去してください。
■「~/」はホームディレクトリなので、「./」カレントディレクトリに読み替えて作業する。
「cd」しすぎて大事な空の「a」ディレクトリを消してしまわないようにw。
$ find . -type f -name "b" -exec rm {} \;; \
for n in `seq 1 100`;do cd a;done;for n in `seq 1 99`;do cd ../;rmdir a;done