28

I need an equivalent of the Unix head command (display the first N lines of the output). This is what I'm using currently:

tasklist | find /N " " | findstr /r \[[0-9]\]

The above code displays the first 10 lines of tasklist's output. find /N " " prepends a line number to the start of each line while findstr /r \[[0-9]\] extracts the first 10 lines using regex.

Above code works, but I need to specify any range. Due to the fact that regular expressions are not implemented according to the standards in Windows, I can't get anything else to work.

How can I extract arbitrary lines from a cmd output? It is important to do this with a one-liner. No scripts!

2
  • .....................
    – giecsar
    Mar 28, 2013 at 15:55
  • Nice workaround for a simple usecase, we say: In hard times, the devil eats flies.
    – Timo
    Dec 25, 2020 at 14:20

4 Answers 4

45

Powershell.

PS C:\> netstat | Select -First 20

Edit: I have a feeling that you're going to insist that you're only able to use cmd.exe circa 1989, but that's not true. Powershell is baked into every OS version Vista+, and is installable on XP/2003. It is the future of Windows.

Edit: Alright, have it your way.

C:\> netstat -an > temp.txt && for /l %l in (1,1,10) do @for /f "tokens=1,2* delims=:" %a in ('findstr /n /r "^" temp.txt ^| findstr /r "^%l:"') do @echo %b

Will display the first 10 lines of the output of netstat.

8
  • 8
    I have no doubt that PowerShell is the future, but I need something that works, now. In an enterprise reality, often the customers of our tech support department have hundreds of windows servers, none of which have Vista, 7 or 8. I can't possibly waste time installing PowerShell every time I need to run a command, nor am I even authorized to.
    – giecsar
    Mar 28, 2013 at 15:56
  • 1
    Cmd.exe it is...
    – Ryan Ries
    Mar 28, 2013 at 16:35
  • all they would need is one w2k8r2 server that they CAN log into to run a powershell command, is that possible?
    – tony roth
    Mar 28, 2013 at 16:46
  • I don't know if there are 2K8 servers, but Ryan Ries's answer is exactly what I needed. Thank you very much Ryan!
    – giecsar
    Mar 28, 2013 at 17:02
  • 3
    Please don't forget to... mark the answer as... accepted... :`( curls up in fetal position in the corner and sobs to self
    – Ryan Ries
    Apr 1, 2013 at 23:18
7

If you are a Unix type person, perhaps installing CygWin gives you a more familiar environment.

2
  • 3
    No, I thought I made it clear, but I can't installing anything. It must run with the Windows command processor (cmd.exe). No PowerShell, no CygWin, no scripts.
    – giecsar
    Mar 28, 2013 at 16:00
  • Plz. remove Cygwin, cannot see it anymore. It is from yesterday.
    – Timo
    Dec 25, 2020 at 14:23
5

There's an easy solution that's much easier than using the "for" loop.

Let's take the output from dir/o-d (dir inverse-ordered by date) as an example.

E.g. if you want to output lines 1 to 16, use:

dir/o-d|findstr/n ^^|findstr "^[1-9]: ^1[0-6]:"

E.g. if you want to output lines 16 to 45, use:

dir/o-d|findstr/n ^^|findstr "^1[6-9]: ^[2-3][0-9]: ^4[0-5]:"

Sample output:

16:08/08/2016  08:43 AM    <DIR>          nacl_sdk
17:11/05/2016  10:48 PM    <DIR>          3b 2
18:28/04/2016  02:47 PM    <DIR>          sample
19:22/04/2016  10:07 PM    <DIR>          mysql test
20:16/04/2016  01:22 AM    <DIR>          3b
21:16/04/2016  01:10 AM             2,706 errorlog
22:16/04/2016  12:53 AM                 0 accesslog
...

Breakdown:

  1. First, dump the whole output using dir/o-d.

  2. Next, prepend each line with "$Num:" using findstr/n ^^

    • ^ means match start of line, and ^^ is simply it's escaped version required because we are in cmd.

    • Note: you need to use findstr for this because find/n" " will not match lines without spaces`.

  3. Lastly, crop the output using findstr "^1[6-9]: ^[2-3][0-9]: ^4[0-5]:".

    • ^1[6-9]: is regex for 16 to 19.

    • ^[2-3][0-9]: is regex for 20 - 39.

    • ^4[0-5]: is regex for 40 to 45.

    • findstr "a b c" means find strings which match either expressions a, b, or c.

Also see https://stackoverflow.com/q/8844868/632951

2
  • That's a nice solution, but you now have the number prefixed there, can one get rid of them in the last findstr call?
    – fschmitt
    Sep 30, 2015 at 15:26
  • @fschmitt, findstr cannot remove things. I'd think you might be forced to use a loop then in that case.
    – Pacerier
    Nov 26, 2015 at 4:39
1

This is a one-line-command, I hope it works for you too.

@echo off&cls&for /f "tokens=*" %a in (Graph.bat) do echo %a&for /f "skip=1 tokens=*" %a in (Graph.bat) do echo %a&for /f "skip=2 tokens=*" %a in (Graph.bat) do echo %a&for /f "skip=3 tokens=*" %a in (Graph.bat) do echo %a&for /f "skip=4 tokens=*" %a in (Graph.bat) do echo %a&pause>nul

:: Run this from CMD.exe and make sure that your file is in your current working directory.

::Replace Graph.bat with your file.
1
  • Will this work for lines starting with semicolon ; or blank lines?
    – Zimba
    Apr 16, 2020 at 14:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .