DOSバッチファイルでのfor文とcall文等について
複数のファイルをcopyコマンドで一つに連結し、sortコマンドでソートした後、重複行を削除したいと思い、 UNIXでのuniqコマンドに相当するものがWINDOWSでもないかと探してみました。
ちなみに、uniqコマンドとは、重複行を単一行のユニーク(uniq)にするコマンドです。
http://www.fpcu.jp/dosvcmd/bbs/log/unixdoswindows/3-0062.html
そこにDOSバッチファイルでのuniqコマンドもどき(uniq.bat)のソースがありました。しかし、たった14行のソースなのですが全く読めません(わかりません)。そこで、調べてみました。以下はそのメモです。
uniq.batのソースの引用
ソース説明
1の『echo off』
エコーオフです(そのまんま)。ちなみに、エコーオンでコマンドを実行すると、コマンド実行文そのものやその実行結果が、すべてコマンドプロンプトに出力される。エコーコマンドのみのエコー出力をしたい場合は、『echo off』にします。また、『echo off』自体もオフにしたい場合は『@echo off』とします。
2の『set prev=』
環境変数の設定です。重複を求めるために読み込んだ一行分データを格納する変数です(この段階ではなにも設定していない)。
4の『for /f "tokens=* delims=" %%L in ( %1 ) do call :sub %%L』
第一引数(%1)で指定されたファイルから一行読み込んで変数『%%L』にセットし、別プロセス(call)でサブルーチン『sub』を、引数に『%%L』の値をセットして呼んでいます。これを、ファイルのすべての行に対して繰り返『for』します。
for文に関して詳しい説明は、以下を参照願います。
http://forum.nifty.com/fpcu/dosvcmd/batch.htm#for
補足:『sub』は同ソース上にありますが、『call』で呼ばれたときには、呼び側プロセスと別プロセスになり、『goto :EOF』を実行後、呼び側プロセスに戻ってきます。また、『%%L』は、バッチファイル内では%%Lですが、コマンドプロンプトに直接入力の時は%Lとなります。
5の『goto exit』
『goto exit』して処理を終了しています。
6の『:sub』
サブルーチンです。別プロセスになります。
7の『if not "%prev%"=="%*" set prev=%*&&echo %*』
環境変数prevとサブルーチン全引数をまとめたもの(%*)、つまり、一行読みデータが等しくないかを判断し、もしそうなら、環境変数prevに一行読みデータ(サブルーチン全引数のまとめもの(%*))を設定しなおして、そのコマンドが成功したら(&&)、一行読みデータ(%*)をエコーする。
補足:&&は、直前のコマンドが成功したら&&以降を実行すること。また、%1〜%9は、引数の個数分に対応しており、%*は、それをすべてまとめたもの。
8の『goto :EOF』
WindowsNT/2000/XPでは、あらかじめ暗黙に定義された「ファイル末尾」を意味するラベル 『:EOF』 が利用できる。
uniq.bat使用例
C:\Documents and Settings\xxx>type test.txt 123456789 111111111 111111111 111111111 222222222 C:\Documents and Settings\xxx>uniq test.txt C:\Documents and Settings\xxx>echo off 123456789 111111111 222222222
uniqコマンドを実行したことにより、111111111の行がユニークになりました。