head コマンドその後

以前、head コマンドについて書いたが、ふと思い立って続編の tail コマンドを書いてみようかと思った。
前回のスクリプトは行入力と head のメインロジックが混じっており、ちょっと汚いので1行入力部分を :getline というサブルーチンにしてみた。

:getline の仕様は、

  • 第一引数に入力行が返る
  • EOF なら第一引数が not defined となる
  • 第二引数に入力された行の前の空白行の行数が返る

制約は以前書いた通りだが、

  • パイプ入力は不可
  • 連続した100行の空行はEOFと見なす
  • ファイル末尾の空行は無視

あと、

  • 処理中にctrl-Cを押すと、「バッチジョブを終了しますか(Y/N)?」に対して、ファイルがリダイレクト入力されているので、キーボードからYもNも入力できない
@echo off
setlocal enabledelayedexpansion
if not defined LINE set LINE=20
if not exist "%~1" exit /b 1
call :head < %1
goto :eof

:head
set L=0
:loop
 call :getline DATA SPC
 if not defined DATA goto :eof
 set /a L=L+1+SPC
 if %L% gtr %LINE% goto :eof
 for /l %%I in (1,1,%SPC%) do echo.
 echo !DATA!
goto loop

:getline
set %2=0
:g1
set %1=
set /p %1=
if not defined %1 (
 if !%2! geq 100 goto :eof
 set /a %2=%2+1
 goto g1
)