前回書いた2つの方法で書いた tail コマンドの基幹部分を示す。
(1) 中間ファイル方式
set I=-%LINE% set J=0 for /f "delims=" %%A in ('more %1') do ( set /a J+=1, I+=1 echo.%%A>%TEMPFILE% call set /p SAVE%%J%%=< %TEMPFILE% call set "SAVE%%I%%=" ) set /a I+=1 if %I% leq 0 set I=1 setlocal enabledelayedexpansion for /l %%K in (%I%,1,%J%) do echo.!SAVE%%K! del /f %TEMPFILE% 2>NUL goto :eof
(2) for (%%) 方式
set I=-%LINE% set J=0 for /f "delims=" %%A in ('more %1') do ( set /a J+=1, I+=1 for /f "delims=" %%B in ('echo SAVE%%J%%') do set %%B=%%A call set "SAVE%%I%%=" ) set /a I+=1 if %I% leq 0 set I=1 setlocal enabledelayedexpansion for /l %%K in (%I%,1,%J%) do echo.!SAVE%%K! goto :eof
これと、(3) [続]tailコマンドの作成で書いた、more + を使った方式とで処理時間を比べてみた。テストでは 1000行、約32KB のファイルに対して、tail -10 を行った。結果は、
(1) 25 秒
(2) 99 秒
(3) 1 秒
である。(3) が早いのは当然として、(2)が遅いのはサブシェル起動に時間が掛かっているためと思われる。検証のために、
for /l %I in (1,1,1000) do @cmd /c "@rem"
と、
for /l %I in (1,1,1000) do for /f %J in ('rem') do @echo.
の時間を計ってみると、それぞれ、102秒、75秒である。(2) の結果とも考え合わせると、for /f (' ') によるサブシェル起動は、明示的に cmd を起動するよりは効率よく出来ているようだ。
結論としては、いくら“パイプ入力にも対応”“中間ファイルを使わない”という利点があるとしても(2)は遅すぎる。オペランドでファイルを与えた時は(3)で、そうでない場合は(1)の方式をそれぞれ使うようにするのがいいかと思う。