コマンドラインで.svnディレクトリを一括削除2008年08月04日 01時05分23秒

DIR コマンドにこんな使い方が

なにを探しているときに見つけたかすでに忘れたのだが、しばらく前にこんなTIPSを見つけた。

タイトルにあるとおり、

dir /b/s somedir
ってやると、UNIX/Linuxのfindコマンドよろしく、指定ディレクトリ以下のファイルをフルパスで列挙してくれる。

例えば、dara-jの手持ちの環境ではZend Framework 1.0.0を D:\PHP\libs\Zend 以下に設置しているのだが、こんな感じで列挙できる。

C:\Documents and Settings\dara-j>dir /b/s D:\PHP\libs\Zend\*.php
D:\PHP\libs\Zend\Acl.php
D:\PHP\libs\Zend\Auth.php
D:\PHP\libs\Zend\Cache.php
D:\PHP\libs\Zend\Config.php
D:\PHP\libs\Zend\Date.php
D:\PHP\libs\Zend\Db.php
D:\PHP\libs\Zend\Debug.php
 :
(中略)
 :
D:\PHP\libs\Zend\XmlRpc\Value\DateTime.php
D:\PHP\libs\Zend\XmlRpc\Value\Double.php
D:\PHP\libs\Zend\XmlRpc\Value\Exception.php
D:\PHP\libs\Zend\XmlRpc\Value\Integer.php
D:\PHP\libs\Zend\XmlRpc\Value\Scalar.php
D:\PHP\libs\Zend\XmlRpc\Value\String.php
D:\PHP\libs\Zend\XmlRpc\Value\Struct.php

C:\Documents and Settings\dara-j>
はぁ、こんなことできたんだぁ。

ヘルプで調べてみると

dir /?でそれぞれのオプションがどんな意味があるのか見てみたところ、

/B ファイル名のみを表示します (見出しや要約が付きません)。
dir /? より抜粋
/S 指定されたディレクトリおよびそのサブディレクトリのすべての ファイルを表示します。
dir /? より抜粋

なるほど、/bで属性などをつけずファイル名(というより、絶対パスみたいなのだが)のみ、/sで再帰処理なことはよくわかった。しかし、何度かこの説明文は見たことあるんだけど、さっぱり気がつかなかった。

その列挙を利用して...

これだけでも割と目から鱗チックだったんだけど、リンク先にはさらにこんなコマンドが載っていた。

リダイレクトしない場合はforコマンドが使えます。

C:\Inetpub\wwwroot> for /f %d in ('dir /b/s _vti_cnf') do rmdir /q/s %d

うーん、よくわからんが、どうやらIISがらみの特定のディレクトリかファイルを再帰処理で一括削除しているみたい。

つか、FORコマンド??

for /?で見てみると(長いヘルプなのでテキストファイルに書き込むと吉)、どうやらこれが該当するのかな。

FOR /F ["オプション"] %変数 IN ('コマンド') DO コマンド [コマンド パラメータ]
for /? より抜粋
説明を見てもなんだか冗長でイマイチ把握しづらいんだけど、()内の一重引用符で囲まれた「dir /b/s _vti_cnf」の結果を変数 %d に逐次当てはめながら、do 以降で指定されているコマンド「rmdir /q/s %d」に渡しているんだろうと。

なるほどねぇ、dir /b/s でファイルのフルパスがあがってくるので、これをforコマンドにまわせばループ処理できるんだ。

.svnディレクトリを再帰的に削除してみたり

んで、やっとこ本題。

Subversionの作業コピーって、各ディレクトリにメタデータディレクトリ「.svn」が隠しディレクトリとして追加されてるのよね。

ローカルで作業してるときはいいんだけど、これをどっかに配布したりするのに、このメタデータが邪魔なので削除してみようかと。いや、当然エクスポートすればいいのは知ってるんだけどね。

いきなり結論。

for /f "tokens=*" %d in ('"dir /b/s/a | findstr /r \.svn$"') do rmdir /q/s "%d"

ここにいたるまで若干の紆余曲折はあったんだけど、要点は以下。
  • dirコマンドには /aオプションもつける → .svnディレクトリが隠し属性だから。
  • .svnディレクトリだけ処理したいので、findstrで「\.svn$」という正規表現で限定してる。もっとうまいやり方あるかな。
  • dir → findstrとパイプでうまくつなげるには二重引用符でくくる。上のコマンドをよーく見てみて。
  • パスに空白が入る場合に対応して、/fの後にオプション「tokens=*」で1行すべてを1トークンとして認識させる
  • 同様に空白対策で、rmdirに渡すときに、%d自体を二重引用符でくくる
特にパイプ処理を通すためにコマンド自体を一重引用符の内側でさらに二重引用符でくくるってのはどうやって見つけたか忘れたけど結構ハマってたりして。

うん、こんな覚えづらいコマンドでちくちくするより「svn export --force work_dir target」したほうがよっぽど速いんだけども。

追記(08.9.7)

svn exportはおいておいて、dirコマンドのオプションでもう少し簡単になりました

FORコマンドで遊んでみる。2008年08月04日 01時52分38秒

いや、実用性はないんだけども、前のエントリで覚えたばかりのFORコマンドと、ちょっと前に作ったなんちゃってコマンドを組み合わせて遊んでみたり。

chkconfig.jsの--detailを連続で

chkconfig.jsにオマケでつけてた--detailオプション、サービス名を指定しないと使えない仕様なんだけども、これをFORコマンドと組み合わせて使ってみると。

コマンドラインからcscript付きで指定するとちょっと冗長なので、ラッパーのバッチファイルを作っておくことにしよう。こんな感じで、「chkconfig.bat」とか「chkconfig.cmd」とか。

@echo off
cscript //nologo "%~dP0\scripts\chkconfig.js" %*

dara-jは特定のディレクトリにバッチ(というか.cmdファイル。単なる好みだけど)を設置することにしていて、そこにサブディレクトリ「scripts」を切って.jsはそこに置くようにしているので、chkconfig.jsのパス指定で「%~dP0\scripts\」としている。んで、バッチをおいたディレクトリにパスを通している。

で、chkncofig --listでサービスを列挙した後にfindstr Manualで手動起動設定になっているサービスのみに絞り込んで、それらに対してchkconfig --detailを適用してみる。

C:\Documents and Settings\dara-j>for /f "tokens=1" %d in ('"chkconfig --list | f
indstr Manual"') do @chkconfig --detail %d
サービス名 : AppMgmt
表示名     : Application Management
スタートアップの種類 : 手動
状態       : 停止中
説明 :
  割り当て、公開、削除などのソフトウェアのインストール サービスを供給します。

サービス名 : aspnet_state
表示名     : ASP.NET 状態サービス
スタートアップの種類 : 手動
状態       : 停止中
説明 :
  ASP.NET の out-of-process セッション状態のサポートを提供します。このサービスが
中止されると out-of-process 要求は処理されません。このサービスが無効になると、こ
のサービスに明示的に依存しているサービスはすべて開始できなくなります。
 :
(中略)
 :
サービス名 : xmlprov
表示名     : Network Provisioning Service
スタートアップの種類 : 手動
状態       : 停止中
説明 :
  自動ネットワーク提供のための XML 構成ファイルをドメインごとに管理します。


C:\Documents and Settings\dara-j>

結構重たい上なんの役にも立たないんだけども。

FORコマンド中で「tokens=1」と指定しているのは、chkconfig --listの出力結果からサービス名のみを抽出するため。FORコマンドの既定の区切り文字(空白とタブ、らしい)で各行がトークン単位に分割されるのだが、chkconfigの出力の場合は、先頭がサービス名になるのでそのように指定している。

killでメモ帳を全て終了

今度は多少は使い道あるかなぁ。こちらの「ps.jsとps.cmd / kill.cmd」で作ったpsとkillを使って、特定のプロセスをまとめて終了させると。

まず適当にnotepadをいくつか起動する。

C:\Documents and Settings\dara-j>ps | findstr notepad
 1456  5788 dara-j               4708     4708    0:00:00 notepad.exe
 5316  5788 dara-j               4852     4852    0:00:00 notepad.exe
 4228  5788 dara-j               4716     4716    0:00:00 notepad.exe
 4992  5788 dara-j               4720     4720    0:00:00 notepad.exe
 5544  5788 dara-j               4696     4696    0:00:00 notepad.exe

C:\Documents and Settings\dara-j>

こんな感じで5個のメモ帳が動いてるとして、
C:\Documents and Settings\dara-j>for /f "tokens=1" %d in ('"ps | findstr notepad
"') do @kill %d

C:\Documents and Settings\dara-j>

ってな感じでnotepad.exe全殺し。やっぱ役に立たないかな。

KomodoのZFテンプレートが修正されていた件2008年08月04日 12時03分50秒

前にKomodo Edit取り上げた時に「これ、大丈夫なんかいや?」と思っていたZFのプロジェクトテンプレートのアクションコントローラのファイル名、現時点の最新版の4.4.1では修正されてたみたいね。 リリース直後(7/24だか25だか)に何も考えず更新してたんだけど、ここしばらくは既存プロジェクトのメンテナンスばっかりで新しいコントローラ追加してなかったから気づかなかったわ。

さっきちょっとテストアプリ作ってみようと思って新規コントローラ追加したら、ファイル名が普通に大文字から開始されてて、おや?と思って改めてリリースノート見たら、

Zend Framework: MVC project template fixes. (Bug 78464, 78163)
ってあって、Bug 78464を見に行ってみたら
controller files need to be capitalized, eg IndexController, not indexController
って、ちゃんとバグとして報告あがってたのね。よかった、よかった。