Is there a way to emulate the head command in Windows cmd?

2k views Asked by At

I'm trying to get the first few lines of a huge text file (100K records of a DB table) and it's too large to really manipulate in a text editor.

If I was in linux, I'd use head. I know I can use

more +99995 dbfile.txt

to get the last 5 lines in the file. Is there an equivalent (and simple) method of getting the FIRST lines and logging like this?

Thank you.

(Please note that being able to log this is a must).

2

There are 2 answers

0
AudioBubble On

Why mention toys like Unix in a Windows group. Not smart are you.

Cut

filter cut {t|b} {i|x} NumOfLines

Cuts the number of lines from the top or bottom of file.

t - top of the file
b - bottom of the file
i - include n lines
x - exclude n lines

Example

cscript //nologo filter cut t i 5 < "%systemroot%\win.ini"

The script

Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
Set rs = CreateObject("ADODB.Recordset")
With rs
    .Fields.Append "LineNumber", 4 

    .Fields.Append "Txt", 201, 5000 
    .Open
    LineCount = 0
    Do Until Inp.AtEndOfStream
        LineCount = LineCount + 1
        .AddNew
        .Fields("LineNumber").value = LineCount
        .Fields("Txt").value = Inp.readline
        .UpDate
    Loop

    .Sort = "LineNumber ASC"

    If LCase(Arg(1)) = "t" then
        If LCase(Arg(2)) = "i" then
            .filter = "LineNumber < " & LCase(Arg(3)) + 1
        ElseIf LCase(Arg(2)) = "x" then
            .filter = "LineNumber > " & LCase(Arg(3))
        End If
    ElseIf LCase(Arg(1)) = "b" then
        If LCase(Arg(2)) = "i" then
            .filter = "LineNumber > " & LineCount - LCase(Arg(3))
        ElseIf LCase(Arg(2)) = "x" then
            .filter = "LineNumber < " & LineCount - LCase(Arg(3)) + 1
        End If
    End If

    Do While not .EOF
        Outp.writeline .Fields("Txt").Value

        .MoveNext
    Loop
End With
0
Andry On

head.bat:

@echo off

setlocal DISABLEDELAYEDEXPANSION

set "NUM=%~1"
if "%NUM%" == "" set NUM=0

set LINE_INDEX=0

for /F "usebackq delims=" %%i in (`findstr /B /N /R /C:".*"`) do (
  set LINE_STR=%%i
  call :IF_OR_PRINT %%NUM%% NEQ 0 if %%LINE_INDEX%% GEQ %%NUM%% && exit /b 0
  set /A LINE_INDEX+=1
)

exit /b 0

:IF_OR_PRINT
if %* exit /b 0
setlocal ENABLEDELAYEDEXPANSION
set OFFSET=0
:OFFSET_LOOP
set CHAR=!LINE_STR:~%OFFSET%,1!
if not "!CHAR!" == ":" ( set /A OFFSET+=1 && goto OFFSET_LOOP )
set /A OFFSET+=1
echo.!LINE_STR:~%OFFSET%!
exit /b 1

usage:

type file | head.bat 1000

Features:

  • Prints all characters including control characters like !%^&|> and so.
  • Does not consume empty lines.

Issues:

  • findstr truncates lines longer than 8180 characters ("FINDSTR: Line NNN is too long" message)
  • Not so fast, prints ~2000 lines about 8 seconds on 3.2GHz AMD processor