読者です 読者をやめる 読者になる 読者になる

バッチファイルで逆クオート展開?

Windowsユーザなのに bash に頼りすぎたくない

逆クオート展開、というかバッククオート展開を使いたくて NYACUS を使っているような気もする私ですが、これまでシェルスクリプト的なものは bash スクリプトを書いて、NYACUS から bash に渡して実行していました。

これが段々忌々しくなってきて、近頃はバッチファイルを書いたりするようになってきたのですが、バッククオート展開がわかりません。出来るのかどうかもわかりません。Windowsコマンドプロンプトやバッチファイルに関するヘルプを見ても、コマンド中心にヘルプが構成されていてわかりません。Google 様に聞いてもいまいちわかりません!。

従って 2ch 様を眺めていたら FOR を使って実現していたので、きっとこれがこういうノウハウなんだろうということで理解しました。下のは、引数にファイルのリストを渡すと、各ファイルに sed をかけて、一時ディレクトリに同じ階層作ってそこに書き出して、最後に diff するというバッチです。basename やら diff やらは NT版UNIX-like tools です。

@echo off
setlocal EnableDelayedExpansion 

for %%I in ( %* ) do (
	echo "======================================="

	if exist %%I (
		echo "editing %%I > c:\tmp\%%I"

		for /f %%a in ('basename -d %%I') do set current=%%a
		mkdir "c:\tmp\!current!" 2>NUL

		sed -f "c:\Program Files\nyacus219\scripts\test.sed" %%I > c:\tmp\%%I
		diff %%I c:\tmp\%%I
	) else (
		echo "naiyo %%I:"
	)

	echo "======================================="
)
endlocal

太字のところですが、FOR 文を /F オプション付きで実行すると、普通文字列のリストを入れるようなところにバッククオートで囲ったコマンドを入れることができる。その他、FOR 文がかなり高機能なので 2ch のスレッドを見ているとみんな FOR を自由自在に使いまくりですごい。通常は当然 basename コマンドなんかに頼らずに、同じことを FOR だけで実現されているようです。

実は、

Windows DOS/コマンドプロンプト辞典

Windows DOS/コマンドプロンプト辞典

この本をビックカメラのポイントで買っていたのですが、さすがに想定読者と違ったようです。プロンプト上で各コマンドのヘルプを見た方が色々わかります。ただし例えば変数展開のタイミングの話とか、変数展開の際の文字列操作の話なんかも各コマンドのヘルプの中に散らばっていて、一旦コツをつかむまでがしんどかった。

ちなみに上のバッチを書く際に知ったことは他にも…、

引数の受け取り方

上の本には、%0 から %9 の話しか載っていなくて、引数を一度に全て欲しい時にどうしたらいいのかわかりませんでしたが、%* で受け取れました!。call コマンドのヘルプを見ていて初めて知ったのでした。

ローカル変数(?)の話

バッチファイルで変数使ったら、それは環境変数。当たり前ですか?。いやあ…。なので、このバッチファイルの中だけで有効な「環境変数の変更」を設定するために、setlocal する。終わりは endlocal する。しなくても最後にされる。setlocal にはオプションを指定できて…、

「遅延環境変数の展開」につづく