### 概要 先日、「第9回寒中シェル芸勉強会&第27回バナナで釘が打てますUSP友の会定例会」(http://usptomo.doorkeeper.jp/events/8339)にリモートで参加しまして。
https://twitter.com/kunst1080/status/434556029561344000
当日は普通にFreeBSD上のzshとかbashとかでやりましたが、今日はその問題をWindows7上のコマンドプロンプト(cmd.exe)でやってみようと思います。
#### コンセプト 今回の問題は、ファイル操作系がメインでした。ファイル操作はcmdでも普段から割とやる感じです。
普段のノリでcmd叩けばよし。詰んだらワンライナーにこだわらずさっくり!の心構えでいきましょう。※cmd.exeはコマンド拡張機能・遅延環境変数の展開は有効にしておくこと。(/V オプションを付けて起動)
### 第1問 ファイルを、先頭1文字目の名前のディレクトリへ移動する ```dosbatch rem 1ファイルずつ作成。 copy nul apple copy nul avocado copy nul banana copy nul cinnamon copy nul melon mkdir a mkdir b mkdir c mkdir m

rem echoでコマンドを確認 for /f “usebackq tokens=*” %a in (dir /a-d /b) do @(set X=%a && echo move !x! !X:~0,1!)

rem echoを外して実行! for /f “usebackq tokens=*” %a in (dir /a-d /b) do @(set X=%a && move !x! !X:~0,1!)

rem 結果確認 dir /s /b C:\usr\workspace\cmd\20140215\Q1\a C:\usr\workspace\cmd\20140215\Q1\b C:\usr\workspace\cmd\20140215\Q1\c C:\usr\workspace\cmd\20140215\Q1\m C:\usr\workspace\cmd\20140215\Q1\a\apple C:\usr\workspace\cmd\20140215\Q1\a\avocado C:\usr\workspace\cmd\20140215\Q1\b\banana C:\usr\workspace\cmd\20140215\Q1\c\cinnamon C:\usr\workspace\cmd\20140215\Q1\m\melon

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
</div>
<div class="section">
    ### 第2問
    ファイル名に含まれる空白をアンダーバーにしてリネームする
```dosbatch
rem ファイル作るよ!
copy nul "私は 蟹"
copy nul "オシャレな 蟹"
copy nul "足が 10本"

rem echoでコマンドを確認
for /f "usebackq tokens=*" %a in (`dir /a-d /b`) do @(set X=%a&amp;&amp; echo ren "!x!" "!X: =_!")

rem echoを外して実行!
for /f "usebackq tokens=*" %a in (`dir /a-d /b`) do @(set X=%a&amp;&amp; ren "!x!" "!X: =_!")

rem 結果確認
dir /b
  オシャレな_蟹
  私は_蟹
  足が_10本

```問1とだいたい同じですね。<br/>
<br/>


</div>
<div class="section">
    ### 第3問
    ディレクトリを適当に作って、20140101から20141231まで、日付に対応したファイルを作成。<br/>
フィアル内にはdateコマンドの実行結果を入れる。普通にやるのは無理なので、有効な日付を判定するコマンドを適当に作成しておきます。isDate.bat<br/>
<script src="https://gist.github.com/kunst1080/9149971.js"></script><br/>

```dosbatch
rem コマンドを確認
for /L %a in (20140101,1,20141231) do @(call isdate %a &amp;&amp; echo %a)

rem リダイレクトを付けて実行!
for /L %a in (20140101,1,20141231) do @(call isdate %a &amp;&amp; echo %a>%a)

rem 結果確認
dir /s /b

```※処理超遅い><  のと、ファイルの中身は手抜き。<br/>
<br/>


</div>
<div class="section">
    ### 第4問
    ファイルの中身を入れ替え
```dosbatch
rem ファイル作るよ!
echo カレー > a_ramen
echo ラーメン > a_cury
echo トマト > b_apple
echo りんご > b_tomato

rem (余談)UNIXではgrepを使いましたが、コマンドプロンプトではfindstrでファイルと中身を並べて確認できます。
findstr . *
  a_cury:ラーメン
  a_ramen:カレー
  b_apple:トマト
  b_tomato:りんご

rem echoでコマンドを確認
(dir /w a_* &amp;&amp; dir /w b_*) | findstr "a_ b_" | for /f "usebackq tokens=1,2" %a in (`findstr .*`) do @echo ren %a tmp &amp;&amp; echo ren %b %a &amp;&amp; echo ren tmp %b
rem echoを外して実行!
(dir /w a_* &amp;&amp; dir /w b_*) | findstr "a_ b_" | for /f "usebackq tokens=1,2" %a in (`findstr .*`) do @ren %a tmp &amp;&amp; ren %b %a &amp;&amp; ren tmp %b

rem 結果確認
findstr . *
  a_cury:カレー
  a_ramen:ラーメン
  b_apple:りんご
  b_tomato:トマト

### 第5問 問3のファイルを各月ごとにtar.gzファイルにするtar.gzとか無理っす。
とりえずフォルダに分けときまーす ```dosbatch rem echoでコマンドを確認 for /f "usebackq tokens=*" %a in (`dir /b 2014*`) do @(set X=%a&& echo if not exist !X:~0,6! mkdir !X:~0,6! && echo move %a !X:~0,6!)

rem echoを外して実行! for /f “usebackq tokens=*” %a in (dir /b 2014*) do @(set X=%a&& if not exist !X:~0,6! mkdir !X:~0,6! && move %a !X:~0,6!)

rem エラー!?ちょっと構文を買えてやりなおし for /f “usebackq tokens=*” %a in (dir /b 2014*) do @(set X=%a&& echo if not exist !X:~0,6! mkdir !X:~0,6! && echo move %a !X:~0,6!)» exec.bat && @cmd /c exec.bat

rem なんかエラー出るけどファイルは移動するorz

rem 結果確認 tree /f フォルダー パスの一覧 ボリューム シリアル番号は 3AC0-14F1 です C:. │ exec.bat │ ├─201401 │ 20140101 │ 20140102 │ 20140103 │ 20140104 以下略!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</div>
<div class="section">
    ### 第6問
    mkdir -p `jot -s / -b a 100` &amp;&amp; touch `jot -s / -b a 100`/b &amp;&amp; cd `jot -s / -b a 100` するやつ
```dosbatch
rem 3階層くらいで実験
(for /L %a in (1,1,3) do mkdir a &amp;&amp; cd a) &amp;&amp; copy nul b
cd ..\..\..
rd /s a

rem 一気に実行!
(for /L %a in (1,1,100) do mkdir a &amp;&amp; cd a) &amp;&amp; copy nul b

rem 結果確認
echo %CD%
 C:\usr\workspace\cmd\20140215\Q6\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a\a

```結果確認その2。<br/>
とりあえず、標準入力を指定文字で分割するスクリプトを作っておいた。sepa.bat<br/>
<script src="https://gist.github.com/kunst1080/9148550.js"></script>これを使って、aディレクトリの数を以下のように確認できる。
```dosbatch
echo %CD% | sepa "\\"
echo %CD% | sepa "\\" | find /c "a"

### 第7問 先ほど作ったファイルbを、50番目のaディレクトリに移動する。 ```dosbatch rem とりあえず、元のディレクトリに戻ってから。 rem ディレクトリ名を作成できるか実験 set X1= && (for /L %a in (1,1,100) do @set X1=!X1!a\) && echo !X1!

rem いけそうなので実行。ただし、面倒なので分割実行。 set X1= && (for /L %a in (1,1,100) do @set X1=!X1!a) && echo !X1! set X2= && (for /L %a in (1,1,50) do @set X2=!X2!a) && echo !X2! move %X1%b %X2%b

rem 結果確認 dir /s /b b dir /s /b b | sepa “\” | find /c “a”

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
</div>
<div class="section">
    ### 第8問
    先ほど作ったディレクトリについて、rm -rを使わずに~/a以下のディレクトリを消去してください。rm -r じゃなくて rd /s /q ・・・という冗談はさておき。delとrmdirで消していきます。
```dosbatch
for /L %a in (1,1,99) do @cd a &amp;&amp; for /L %a in (1,1,100) do @(rmdir a &amp;&amp; cd .. &amp;&amp; if exist b del b)

```なぜか「ディレクトリが空ではありません。」というエラーが出るが、実際には空なのでディレクトリはちゃんと削除されてる。<br/>
一応、最後まで普通にやれました。

</div>