head コマンド再び

昨日書いたように、for 文中での環境変数の直近値の参照方法はいろいろある。そこで、 以前あきらめた head コマンドの for /f での実現をやってみた。ただし、空行はスキップされると言う for /f の仕様だけは我慢することになる。一方、副産物だが、do ( ) の部分を do ('more %1') とすることで、
(1) 引数無しの時にパイプ入力にも対応できる
(2) UTF-16 のファイルでもOK
というメリットも出来た。

@echo off
setlocal
set MORE=
if not defined LINE set LINE=20
set OPT=0
set /a "OPT=%1" 2>NUL >NUL
set /a OPT*=-1
if %OPT% gtr 0 set LINE=%OPT%&shift /1 
set L=0
for /f "delims=" %%A in ('more %1') do (
 call :check
 if ERRORLEVEL 1 goto :eof
 echo.%%A
)
goto :eof
:check
set /a L+=1
if %L% gtr %LINE% exit /b 1
exit /b 0

! < | > & ^ 等の特殊文字を含んだファイルもOK。dir | head -10 もOK。
意外と簡単だったので、ついでに、行数オプションにも対応。ただし、

set /a "OPT=%1" 2>NUL >NUL

と、手抜きのためちょっと無理やりなところがあるので、穴があるかも。
複数ファイルの引数にも対応しようかと思ったけど、そうすると、引数無しの場合を別扱いしないといけないので止めた。

先日のものに比べると欠点は空行が扱えないだけで、利点が大きいので前のは捨てよう。次回は tail の書き直し版。