18

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!

| improve this question | |
38

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.

| improve this answer | |
  • 5
    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
  • 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
  • 2
    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 '13 at 23:18
8

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

| improve this answer | |
  • 2
    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
3

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

| improve this answer | |
  • 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 4:39
0

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.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.