Extract N lines from file using single windows command
Asked Answered
W

9

34

Is there a way to extract/copy the fist X number of lines from a file and input them into another file with a single command using the windows command prompt?

I can delete the first X number of lines using:
more +X [file_containing data] > [file_to_export_data_to]

If the head command would work I think I could just do this:
head -X [file_containing data] > [file_to_export_data_to]

But that unfortunately does not work.

It would be great if Windows had a "less" command but again no luck.

I'm a complete novice when it comes to this stuff so I'm sure I'm missing something obvious. I don't want to install anything or use something other than the command prompt.

Thanks

Wivina answered 13/1, 2015 at 22:32 Comment(2)
PowerShell: get-content file | select-object -first 10. (PowerShell is built-in from Windows 7 on.)Durer
POWERSHELL> get-content int.txt | select-object -first 10 > out.txtUnconformable
C
51

the simplest one-command solution is to use Powershell Get-Content.

N - number of lines.

From the begining of file:

Get-Content -Head N file.txt

From the end of file:

Get-Content -Tail N file.txt
Coly answered 25/4, 2016 at 9:12 Comment(4)
I get "A parameter cannot be found that matches parameter name 'Head'." error.Fer
Check version of PowerShell, I assume it is old. Or a typo somewhere in the command.Coly
You may have to use 'TotalCount' instead of 'Head'. See learn.microsoft.com/en-us/powershell/module/…Antonetta
Add ` > tagetfile.txt` at the end of the command, to pipe into a file instead of just displaying.Intratelluric
A
26

You can use PowerShell from the cmd.exe console:

 powershell -command "& {get-content input.txt|select-object -first 10}" >output.txt

You could create a DOSKEY macro to make it easier to use from the command line:

doskey head=powershell -command "& {get-content $1|select-object -first $2}"

Usage:

head input.txt 10 >output.txt

But you cannot use a DOSKEY macro within a batch script.

You could create a head.bat script instead and place it in a folder that is included in your PATH:

head.bat

@powershell -command "& {get-content %1|select-object -first %2}"

From the command line, you would use head input.txt 10 >output.txt

From within a batch script, you would use call head input.txt 10 >output.txt

I chose not to have the output file as a parameter in case you want to simply display the result to the screen instead of writing to a file.

Assumed answered 14/1, 2015 at 16:12 Comment(0)
W
4

In order to get correct utf8 output, do the following in powershell

chcp 65001

$OutputEncoding = New-Object -typename System.Text.UTF8Encoding

get-content input.txt -encoding UTF8 |select-object -first 10000 > output.txt

This will get first 10000 lines of input.txt (file in utf8 format) to output.txt with correct encoding.

Woods answered 6/9, 2016 at 12:4 Comment(0)
O
2
(@FOR /f "tokens=1* delims=:" %a IN ('findstr /n "^" "standardwaffle.txt"') DO @IF %a leq 7 ECHO(%b)>u:\junk.txt

would extract the first 7 lines of standardwaffle.txt to u:\junk.txt so here it is in one cmd line - but I'd defy you to enter that reliably.

It would also remove any leading : on a source line.

@ECHO OFF
SETLOCAL
IF %1 lss 0 (SET /a line=-%1) ELSE (SET /a line=%1)
FOR /f "tokens=1* delims=:" %%a IN ('findstr /n "^" "%~2"') DO IF %%a leq %line% ECHO(%%b

GOTO :EOF

This batch, saved as head.bat placed anywhere on your path would allow you to use

head -n standardwaffle.txt >junk.txt

to extract the first n lines of standardwaffle.txt to junk.txt

the - would be optional

but this involves installing the batch on your machine. Is that banned by your "no installing" requirement, or is "installing" meant only for 3rd party utilities?

Ostap answered 14/1, 2015 at 4:25 Comment(2)
The batch file appears to read the whole file first, as in a file of 500Mb it is taking a lot, and in small files it works instantly. On the other hand, the solution with Powershell by dbenham appears to output the intended part fast, so it can be interrupted while it is still reading the rest of the file.Footnote
I was hoping for a batch/cmd solution too, but I've got a 25GiB file to work with. Definitely don't want it trying to read that into memory. :/Unthread
H
1
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
x = 0
    Do Until Inp.AtEndOfStream
              x = x + 1
        OutP.WriteLine Inp.Readline
              If x = 5 then Exit Do
    Loop

This prints lines 1 to 5. To use

cscript //nologo <path to script.vbs> <inputfile >outputfile
Himeji answered 14/1, 2015 at 4:14 Comment(0)
S
1

you can use this:

break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb  X /t |more +4 | findstr /B /E /V "*****"

where you should replace the X with the lines you want.Or name this head.bat :

break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb  %~1 /t |more +4 | findstr /B /E /V "*****"
Shaper answered 21/9, 2016 at 19:10 Comment(0)
P
0

If you wanted to stick to simple Windows commands you could use this but would be a little slow for large files ;-) (I've added a second solution below that works better :-) this extracts the last 100 records of any length of file)

find /n " " <test.txt >test.tmp
for /l %%i in (1,1,100) do find "[%%i]" <test.tmp >test.tmp2
for /f "delims=] tokens=2" %%i in (test.tmp2) do echo %%i >>test.new
del test.tmp
del test.tmp2
move /y test.new test.txt

find /v /n "" <test.txt >test.tmp
for /f "delims=: tokens=2 %%i in ('find /v /c "" test.txt') do set /a NR=%%i
set /a NS=%NR%-100
for /l %%i in (%NS%, 1, %NR%) do find "[%%i]" <test.tmp >>test.tmp2
for /f %%i "delims=] tokens=2 %%i in (test.tmp2) do echo %%i >>test.new
move /y test.new test.txt
Plankton answered 26/3, 2019 at 11:22 Comment(3)
You are right - this is sloow :). Shouldn't it be >> in the second line? You should also mention where to insert "Startline" and "Endline" (to me it's obvious, but without some experience, it's hard to tell)Diogenes
Yes you're right, sorry my bad (typo) and yes I assumed it would be obvious that 1 and 100 are the start and end lines, you could vary them to extract any portion of the file you wanted on a line number basis.Plankton
Mind expanding your answer to make it a good one? (and it's cmd, not DOS. Your code wouldn't run in DOS)Diogenes
S
0

It should works

echo off
set /p n="Enter the number of rows (n): "
for /f "tokens=1* delims=:" %%i in ('findstr /n "^" "standardwaffle.txt"') do (if %%i leq %n% echo %%j)
Surfperch answered 3/11, 2023 at 12:30 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Saleem
H
-1

No need to read whole file; just extract the required lines (head) from beginning of file:

set file=<file>
set line=<required first few lines>
type nul > tmp & fc tmp "%file%" /lb %line% /t | find /v "*****" | more +2

A single line example to extract first 9 lines from file.txt & write into nine.txt

for /f "tokens=* delims=[" %i in ('type "file.txt" ^| find /v /n "" ^| findstr /b /r \[[1-9]\]') do set a=%i& set a=!a:*]=]!& echo:!a:~1!>> nine.txt

Preserves blank lines, lines starting with semicolon, leading spaces and preserves delimiter and whitespaces.

Tested on Win 10 x64 CMD

Halfslip answered 18/4, 2020 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.