27

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!

Pacerier
  • 521
  • 16
  • 35
giecsar
  • 271
  • 1
  • 3
  • 3

4 Answers4

44

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.

Ryan Ries
  • 55,481
  • 10
  • 142
  • 199
  • 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 '13 at 15:56
  • 1
    Cmd.exe it is... – Ryan Ries Mar 28 '13 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 '13 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 '13 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 01 '13 at 23:18
  • Please could someone explain how the cmd.exe solution works? – user3490 Apr 13 '13 at 22:50
  • @giecsar: what Os are those 'servers' running? – oɔɯǝɹ Apr 20 '13 at 10:44
  • @RyanRies, I don't know why "installable on XP/2003" is such an epiphany.... there're tons of programs that are "installable on XP/2003". – Pacerier Aug 25 '15 at 13:00
7

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

vonbrand
  • 1,149
  • 2
  • 8
  • 16
  • 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 '13 at 16:00
  • Plz. remove Cygwin, cannot see it anymore. It is from `yesterday`. – Timo Dec 25 '20 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

Pacerier
  • 521
  • 16
  • 35
  • 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 '15 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 '15 at 04: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.
phuclv
  • 169
  • 1
  • 16
hidde663
  • 11
  • 1