Windows批处理命令从文本文件读取第一行


84

如何使用Windows批处理文件从文本文件中读取第一行?由于文件很大,所以我只想处理第一行。


1
尝试使用GNU32“ head”实用程序。不要以为仅通过DOS Batch就可以轻松实现您的目标。
Nasir

@Nasir,不能通过内置命令来完成吗?
Prajwal Dhatwalia

Answers:


48

这是一个通用批处理文件,用于打印nGNUhead实用程序之类的文件中的顶行,而不仅仅是一行。

@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

例如:

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

当前不计算空白行。它也受批处理文件行长度限制为8 KB。


10
仅供参考:“ GOTO:EOF”这是一个特殊标签,无需定义特殊的“:exit”标签即可退出脚本。在批处理中定义子例程时(这是什么意思?子例程?是的),它也很有用
Steven

4
这似乎炸毁了我的多个GB文本文件...在一个文件上,它试图返回10行时给了我“内存不足”错误,在另一个文件上,当它要求返回时它只返回了一个空行10行。任何想法为什么会发生这种情况?

1
@丹-行多久?FOR / F“忽略”超过8191字节的行。但是我想知道如果遇到很长的行是否会出现“内存不足”错误。
dbenham

@StephanMuller-看到我对Dan的评论
dbenham

如所写,此答案将忽略空行。它还将忽略以分号;(默认为FOR / F EOL字符)开头的行。如果要求输入10行,则它将打印不为空且开头不是的前10行;
dbenham

224

嗯?imo这要简单得多

  set /p texte=< file.txt  
  echo %texte%

16
+1,这是工作时最好的:-)它具有以下限制1)最大行长度为1021字节,不包括EOL。2)文件必须使用Windows样式的CarriageReturn LineFeed EOL。3)尾随的控制字符将被删除
dbenham

4
同样,在第一行为空白的情况下,在读取文件之前,texte应该明确地未定义。
dbenham

这里有一些修剪琴弦的额外技巧。echo %texte:~3%例如将跳过前三个字符。在读取带有BOM表的UTF-8文件时,这很有用。
KargWare

22

呃你们...

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:\>

2
如果文件有11行以上,它将比第一行打印更多,例如:1:,11:,21:等...
Cesar Romero

1
赶上塞萨尔!我总是尽量避免使用引号,因为它们会使我烦恼,但是在这种情况下,这是个坏主意。修复,更改findstr "^1:"并获得双引号的温暖和保护。或者,如果您不屑一顾像我这样的名言,并想过着危险的生活,请使用findstr /b 1:
阿米特·奈杜

4
如果您希望它不带引号且不带/ b选项,则只需转义插入符号:findstr ^^1
dbenham

很好的提示dbenham,cmd中的转义总是使我逃脱。顺便说一句,请不要对大型文件使用此方法,它实际上会读取整个文件,并且效率很低。我对该解决方案的唯一标准是A)应该是一行B)应该易于记忆或从内存和类型重新创建,而不是复制粘贴C)没有外部工具。set /p对于大型文件,该解决方案效率更高。
阿米特·奈杜

2
而且,它会将行号添加到您实际想要的文本行中!因此,当您只需要文本时就没那么有用了。
Ross Presser

11

您可以尝试一下:

@echo off

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

编辑 或者,假设您有四列数据,并且想要从第5行到底部,请尝试以下操作:

@echo off

for /f "skip=4 tokens=1-4" %%a in (junkl.txt) do (
  echo %%a %%b %%c %%d
)

1
这给了我我需要的线索,但并不完全正确。不知道正确的程序是什么,但是我将此解决方案合并到了最终解决方案中。参见stackoverflow.com/questions/130116#130209
Jesse Vogt

2
该解决方案的问题是它用空格而不是换行符定界,并且文件名不能带空格。您可以使用for循环中的delims和usebackq选项解决这些问题。
indiv 09年

为我工作,但我必须添加"delims="以打印出完整的文件夹名称以及空格。
GChuf


4

稍微建立在其他人的答案上。现在,您可以指定要读取的文件以及要将结果放入其中的变量:

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

这意味着您可以像这样使用上面的代码(假设您将其称为getline.bat)

c:\> dir > test-file
c:\> getline variable test-file
c:\> set variable  
variable= Volume in drive C has no label.

3

一根衬线,可用于使用“>”标准输出重定向:

@for /f %%i in ('type yourfile.txt') do @echo %%i & exit


1

EXIT /B当更实际地将批处理文件作为批处理文件的一部分时,解决方案的问题如下。之后的批处理文件中没有后续处理EXIT /B。通常,批处理不仅仅是一项有限的任务。

为了解决这个问题:

@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

(但是,所谓的毒字仍然是一个问题。)

有关使用批处理命令获取特定行的更多信息:

如何获得文本文件的第n行,第一行和最后一行?” http://www.netikka.net/tsneti/info/tscmd023.htm

[2012年8月28日新增]还可以具有:

@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

设置/ p texte = <file.txt可能是已经提出的最简洁的解决方案。在这个线程中,@ Spaceballs。通常,我会写set / p“ texte” = <“ file.txt”,但这是重点。请注意,即使此解决方案也容易出现毒字问题,即可能会失败,具体取决于file.txt包含的内容。
蒂莫·萨尔米

1

要cicle文件(file1.txtfile1[1].txtfile1[2].txt等):

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%

它正在运行。


对此的解释是:set /p通过提示询问;但是,通过文件重定向,<它会立即在提示符下获取文件的内容;当第一行以行结尾时,提示将停止读取,因此仅将第一行存储在变量中。
sdbbs

0

请注意,批处理文件的方法将限于DOS命令处理器的行限制-请参阅命令行长度限制是多少?

因此,如果尝试处理行数超过8192个字符的文件,脚本将跳过它们,因为无法保留该值。


0

其他方式

setlocal enabledelayedexpansion
@echo off
for /f "delims=" %%i in (filename.txt) do (
if 1==1 (
set first_line=%%i
echo !first_line!
goto :eof
))

2
我建议仅将.bat文件用作万不得已的方法。如果有可能,请始终尝试使用“真实的”脚本语言:Powershell,WSH,Python ...除了.bat文件以外的任何东西。
paulsm4

2
批处理并不是那么糟糕(当您知道时,您在做什么;与所有其他语言相同)。hhay:您的代码无法正常工作。
斯蒂芬

因为您不使用延迟扩展
斯蒂芬

1
@ paulsm4:批处理文件怎么了?它适用于所有Windows版本,并具有称为延迟扩展的独特功能,只要您理解,就可以在不安装第三方软件的情况下发生魔术。您知道在Powershell和dotNet之前很早就可以使用DOS和批处理文件进行TCP / IP吗?
Zimba

0

这是使用方法powershell

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

(您也可以轻松地通过阅读行的范围powershell (Get-Content file.txt)[0..3]

如果您需要在批处理脚本中设置变量作为第一行,则file.txt可以使用:

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

Powershell非常慢
Anic17

-1

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

打印第一行,然后等待用户按一个键打印下一行。打印所需的行后,按Ctrl + C停止。

@Ross Presser:此方法仅打印行,而不在行号前添加行号。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.