98

How can I read the first line from a text file using a Windows batch file? Since the file is large I only want to deal with the first line.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Jesse Vogt
  • 16,229
  • 16
  • 59
  • 72

16 Answers16

242

uh? imo this is much simpler

  set /p texte=< file.txt  
  echo %texte%
Spaceballs
  • 2,559
  • 2
  • 14
  • 9
  • 17
    +1, This is the best when it works :-) It has following limits 1) Max line length of 1021 bytes, not including EOL. 2) The file must use Windows style EOL of CarriageReturn LineFeed. 3) Trailing control characters will be stripped from the line – dbenham Aug 04 '12 at 13:41
  • 5
    Also, texte should be explicitly undefined prior to reading the file just in case 1st line is blank. – dbenham Aug 04 '12 at 13:48
  • 4
    [Here](https://www.dostips.com/DtTipsStringManipulation.php) are some extra tips for trimming the string. `echo %texte:~3%` for example will skip the first three chars. That is usefully when you are reading an UTF-8 file with BOM. – KargWare Jun 03 '20 at 08:36
  • 1
    This is not working. `The syntax of the command is incorrect.` First line was `#include `. So, apparently, `<` and `>` symbol break this... Not the most robust solution. – ScienceDiscoverer Jul 28 '22 at 06:04
52

Here's a general-purpose batch file to print the top n lines from a file like the GNU head utility, instead of just a single line.

@echo off

if [%1] == [] goto usage
if [%2] == [] goto usage

call :print_head %1 %2
goto :eof

REM
REM print_head
REM Prints the first non-blank %1 lines in the file %2.
REM
:print_head
setlocal EnableDelayedExpansion
set /a counter=0

for /f ^"usebackq^ eol^=^

^ delims^=^" %%a in (%2) do (
        if "!counter!"=="%1" goto :eof
        echo %%a
        set /a counter+=1
)

goto :eof

:usage
echo Usage: head.bat COUNT FILENAME

For example:

Z:\>head 1 "test file.c"
; this is line 1

Z:\>head 3 "test file.c"
; this is line 1
    this is line 2
line 3 right here

It does not currently count blank lines. It is also subject to the batch-file line-length restriction of 8 KB.

indiv
  • 17,306
  • 6
  • 61
  • 82
  • 11
    FYI: "GOTO :EOF" That's a special label that will exit the script without having to define a special ":exit" label. It's also useful when defining subroutines in the batch ( what's that you say? subroutines? Yep ) – Steven Dec 05 '08 at 14:36
  • 4
    This seems to bomb out on my several GB text files... On one file it gave me an "Out of Memory" error when trying to return 10 lines, on the other file it just returned a single blank line when asking it to return 10 lines. Any ideas why this happens? – Dan Apr 06 '10 at 15:14
  • 1
    @Dan - How long are the lines? FOR /F "ignores" lines longer than 8191 bytes. But I wonder if the "Out of Memory" error arises if it encounters a really long line. – dbenham Aug 04 '12 at 14:41
  • @StephanMuller - See my comment to Dan above – dbenham Aug 04 '12 at 14:41
  • As written, this answer will ignore empty lines. It will also ignore lines that begin with a semicolon `;`, the default FOR /F EOL character. If asking for 10 lines, then it will print the first 10 lines that are not empty and do not begin with `;`. – dbenham Aug 04 '12 at 14:45
  • @indiv `for /f "usebackq eol= delims="` will not disable the `EOL` character it will set it to ``. A solution to disable the EOL is at [SO: Concatenate two strings...](http://stackoverflow.com/a/9419215/463115) – jeb Aug 28 '12 at 07:32
  • @Dan: is this the same Dan from GalaxyLegion? – Zimba Nov 06 '19 at 13:18
24

Uh you guys...

C:\>findstr /n . c:\boot.ini | findstr ^1:

1:[boot loader]

C:\>findstr /n . c:\boot.ini | findstr ^3:

3:default=multi(0)disk(0)rdisk(0)partition(1)\WINNT

C:\>
Amit Naidu
  • 2,494
  • 2
  • 24
  • 32
  • 2
    If the file has more than 11 lines it will print more than the first, like: 1:, 11:, 21:, etc... – Cesar Romero Oct 19 '11 at 14:39
  • 3
    Good catch Cesar! I always try to avoid quotes because they annoy me, but in this case it was a bad idea. To fix, change to `findstr "^1:"` and gain the warmth and protection of double quotes. Or, if you despise quotes like me and want to live dangerously, use `findstr /b 1:` – Amit Naidu Oct 19 '11 at 21:53
  • 4
    if you want it without quotes and without /b option then just escape the caret: `findstr ^^1`. – dbenham Aug 04 '12 at 13:25
  • Great hint dbenham, the escaping in cmd always escapes me. By the way, please don't use this method for large files, it actually reads the entire file and is very inefficient. My only criteria for this solution were A) It should be a single line B) It should be easy to remember or recreate from memory and type, not copy-paste C) No external tools. The `set /p` solution is far more efficient for large files. – Amit Naidu Aug 21 '13 at 18:39
  • 2
    Also, it prepends the line number to the line of text you actually want! Therefore not so useful when you just needed the text. – Ross Presser Feb 12 '15 at 17:38
  • `findstr /n . downing.txt | findstr ^^1` :prints lines starting with 1 eg. 1, 11, 12, 13. `findstr /n . downing.txt | findstr ^^1:` :prints 1st line only `findstr /n . downing.txt | findstr ^1:` :prints lines containing 1 eg. 1, 11, 21, 31 – Zimba Nov 06 '19 at 14:06
  • I just changed ^1: to :1: and it worked. Neither double quotes nor double ^^ worked for me – airstrike Jan 16 '20 at 23:25
13

You might give this a try:

@echo off

for /f %%a in (sample.txt) do (
  echo %%a
  exit /b
)

edit Or, say you have four columns of data and want from the 5th row down to the bottom, try this:

@echo off

for /f "skip=4 tokens=1-4" %%a in (junkl.txt) do (
  echo %%a %%b %%c %%d
)
Chris Baker
  • 49,926
  • 12
  • 96
  • 115
Ross Fuhrman
  • 638
  • 4
  • 13
  • 26
  • 1
    This gave me the clue I needed but was not quite right. Not sure what the proper procedure was but I incorporated this solution into the final solution. see http://stackoverflow.com/questions/130116#130209 – Jesse Vogt Sep 24 '08 at 21:57
  • 2
    This solution's problem is that it delimits on space instead of newline, and you can't have a filename with spaces. You can fix these issues with the delims and usebackq options in the for loop. – indiv Sep 24 '08 at 23:12
  • Worked for me, but I had to add `"delims="` to print out full folder names together with spaces. – GChuf Jul 25 '20 at 12:32
6

Thanks to thetalkingwalnut with answer Windows batch command(s) to read first line from text file I came up with the following solution:

@echo off
for /f "delims=" %%a in ('type sample.txt') do (
echo %%a
exit /b
)
Community
  • 1
  • 1
Jesse Vogt
  • 16,229
  • 16
  • 59
  • 72
4

Slightly building upon the answers of other people. Now allowing you to specify the file you want to read from and the variable you want the result put into:

@echo off
for /f "delims=" %%x in (%2) do (
set %1=%%x
exit /b
)

This means you can use the above like this (assuming you called it getline.bat)

c:\> dir > test-file
c:\> getline variable test-file
c:\> set variable  
variable= Volume in drive C has no label.
Ray Hayes
  • 14,896
  • 8
  • 53
  • 78
4

powershell Get-Content file.txt -Head 1

This one is much quicker than the other powershell examples above, where the full file is read.

Ingmar
  • 41
  • 1
3

One liner, useful for stdout redirect with ">":

@for /f %%i in ('type yourfile.txt') do @echo %%i & exit
PabloG
  • 25,761
  • 10
  • 46
  • 59
3

Try this

@echo off
setlocal enableextensions enabledelayedexpansion
set firstLine=1
for /f "delims=" %%i in (yourfilename.txt) do (
    if !firstLine!==1 echo %%i
    set firstLine=0
)
endlocal
Sarath Subramanian
  • 20,027
  • 11
  • 82
  • 86
2

Here is a workaround using powershell:

powershell (Get-Content file.txt)[0]

(You can easily read also a range of lines with powershell (Get-Content file.txt)[0..3])

If you need to set a variable inside a batch script as the first line of file.txt you may use:

for /f "usebackq delims=" %%a in (`powershell ^(Get-Content file.txt^)[0]`) do (set "head=%%a")

To test it create a text file test.txt with at least a couple of lines and in the same folder run the following batch file (give to the file the .bat extension):

@echo off
for /f "usebackq delims=" %%a in (`powershell ^(Get-Content test.txt^)[0]`) do (set "head=%%a")
echo Hello
echo %head%
echo End
pause

In the command prompt window that will open, provided that the content of first line of test.txt is line 1, you will see

Hello
line 1
End
Press any key to continue . . .
mmj
  • 5,514
  • 2
  • 44
  • 51
2

To cicle a file (file1.txt, file1[1].txt, file1[2].txt, etc.):

START/WAIT C:\LAERCIO\DELPHI\CICLADOR\dprCiclador.exe C:\LAERCIUM\Ciclavel.txt

rem set/p ciclo=< C:\LAERCIUM\Ciclavel.txt:
set/p ciclo=< C:\LAERCIUM\Ciclavel.txt

rem echo %ciclo%:
echo %ciclo%

And it's running.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Laercio
  • 21
  • 1
  • The explanation for this is: `set /p` asks through a prompt; however with file redirection `<` it immediately gets the contents of the file at the prompt; and as the first line ends with a line ending, at that point the prompt stops reading, and thus stores just the first line in the variable. – sdbbs Dec 16 '19 at 13:47
1

The problem with the EXIT /B solutions, when more realistically inside a batch file as just one part of it is the following. There is no subsequent processing within the said batch file after the EXIT /B. Usually there is much more to batches than just the one, limited task.

To counter that problem:

@echo off & setlocal enableextensions enabledelayedexpansion
set myfile_=C:\_D\TEST\My test file.txt
set FirstLine=
for /f "delims=" %%i in ('type "%myfile_%"') do (
  if not defined FirstLine set FirstLine=%%i)
echo FirstLine=%FirstLine%
endlocal & goto :EOF

(However, the so-called poison characters will still be a problem.)

More on the subject of getting a particular line with batch commands:

How do I get the n'th, the first and the last line of a text file?" http://www.netikka.net/tsneti/info/tscmd023.htm

[Added 28-Aug-2012] One can also have:

@echo off & setlocal enableextensions
set myfile_=C:\_D\TEST\My test file.txt
for /f "tokens=* delims=" %%a in (
  'type "%myfile_%"') do (
    set FirstLine=%%a& goto _ExitForLoop)
:_ExitForLoop
echo FirstLine=%FirstLine%
endlocal & goto :EOF
player0
  • 124,011
  • 12
  • 67
  • 124
Timo Salmi
  • 254
  • 3
  • 3
  • The set /p texte=< file.txt is probably the niftiest solution that has been presented. In this thread by @Spaceballs. In general, I would write set /p "texte"=<"file.txt" but that is beside the point. Note that even this solution is prone to the poison character problems, i.e. may fail depending on what the file.txt contains. – Timo Salmi Jul 26 '12 at 06:10
1

Another way

setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%i in (filename.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))
hhay
  • 19
  • 2
  • 2
    I would recommend using a .bat file ONLY as a last resort. If it all possible, always try to use a "real" scripting language: Powershell, WSH, Python ... ANYTHING but .bat files. – paulsm4 Feb 27 '18 at 07:03
  • 2
    Batch isn't *that* bad (when you know, what you do; same as with every other language). hhay: your code isn't working. – Stephan Feb 27 '18 at 07:47
  • because you don't use [delayed expansion](https://stackoverflow.com/a/30284028/2152082) – Stephan Feb 27 '18 at 08:25
  • 2
    @paulsm4: What's wrong with batch files? It works on all flavors of Windows, and has a unique feature called delayedexpansion, allowing magic to happen without installing 3rd party software, as long as you understand it. Did you know you could TCP/IP with DOS & batch files long before Powershell & dotNet? – Zimba Nov 06 '19 at 11:39
0

Note, the batch file approaches will be limited to the line limit for the DOS command processor - see What is the command line length limit?.

So if trying to process a file that has any lines more that 8192 characters the script will just skip them as the value can't be held.

kevinjansz
  • 638
  • 6
  • 20
0

In Windows PowerShell below cmd can be used to get the first line and replace it with a static value

powershell -Command "(gc txt1.txt) -replace (gc txt1.txt)[0], 'This is the first line' | Out-File -encoding ASCII txt1.txt"

Reference


How can you find and replace text in a file using the Windows command-line environment?

-1

Print 1st line only (no need to read entire file):

set /p a=< file.txt & echo !a!

To print one line at a time; user to press a key for next line:
(After printing required lines, press Ctrl+C to stop.)

for /f "delims=" %a in (downing.txt) do echo %a & pause>nul

To print 1st n lines (without user intervention):

type nul > tmp & fc tmp "%file%" /lb %n% /t | find /v "?" | more +2

Tested on Win 10 CMD.

Zimba
  • 2,854
  • 18
  • 26