■第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