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

99

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


1
尝试使用GNU32的“head”实用程序。不要认为你想要的东西仅仅通过DOS批处理就可以轻松完成。 - Nasir
@Nasir,不能用内置命令完成吗? - Prajwal
16个回答

244

嗯?我认为这样会简单得多。

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

17
+1,当它工作时这是最好的 :-) 它有以下限制:1)每行最大长度为1021个字节,不包括行尾符。2)文件必须使用回车换行符的Windows样式行尾符。3)行尾的控制字符将被剥离。 - dbenham
5
在读取文件之前,应明确将文本设置为未定义,以防第一行为空。 - dbenham
4
这是一些关于字符串修剪的额外提示。例如,echo %texte:~3% 将跳过前三个字符。当您读取带有BOM的UTF-8文件时,这非常有用。 - KargWare
1
这个不起作用。命令的语法不正确。第一行是#include <iostream>。所以,显然,<>符号破坏了它... 这不是最健壮的解决方案。 - ScienceDiscoverer

52

这是一个通用的批处理文件,可以像GNU中的head实用程序一样从文件中打印前n行,而不仅仅是单独的一行。

@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 的批处理文件行长度限制的影响。


11
FYI:"GOTO :EOF"是一个特殊的标签,它可以在不定义特殊的“:exit”标签的情况下退出脚本。在批处理中定义子函数时也很有用(什么?子函数?没错)。 - Steven
4
似乎我的几个GB的文本文件无法正常运行...在一个文件上尝试返回10行时,给了我一个“内存不足”的错误,在另一个文件上请求返回10行时只返回了一个空行。有任何想法为什么会这样? - Dan
1
@Dan - 这些行有多长?FOR /F命令会忽略超过8191字节的行。但我想知道如果它遇到一行非常长的情况下是否会出现“内存不足”错误。 - dbenham
@indiv for /f "usebackq eol= delims=" 不会禁用 EOL 字符,它只会将其设置为 <SPACE>。要禁用 EOL 的解决方案请参见 SO: Concatenate two strings... - jeb
@Dan:这是来自GalaxyLegion的那个Dan吗? - Zimba
显示剩余2条评论

25

嗯,你们这些人......

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
3
好发现,Cesar!我总是试图避免引号,因为它们让我烦恼,但在这种情况下,这是一个坏主意。要修复,请更改为 findstr "^1:" 并获得双引号的温暖和保护。或者,如果你像我一样憎恨引号并想要冒险生活,可以使用 findstr /b 1: - Amit Naidu
4
如果您想在不使用引号和/b选项的情况下使用,则只需转义插入符号:findstr ^^1 - dbenham
很好的提示dbenham,cmd中的转义总是让我困扰。顺便说一下,请不要使用此方法处理大文件,它实际上会读取整个文件,效率非常低下。我对这个解决方案的唯一标准是A)它应该是单行的B)它应该易于记忆或从记忆和键入中重新创建,而不是复制粘贴C)没有外部工具。对于大文件,set /p解决方案更有效。 - Amit Naidu
2
此外,它会在你实际想要的文本行之前添加行号!因此,当你只需要文本时并不是很有用。 - Ross Presser
显示剩余2条评论

13

您可以尝试这个:

@echo off

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

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

@echo off

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

1
这给了我所需的线索,但并不完全正确。不确定正确的程序是什么,但我将此解决方案合并到最终解决方案中。请参见https://dev59.com/u3VC5IYBdhLWcg3w-WSs。 - Jesse Vogt
2
该解决方案的问题在于它以空格而非换行符为分隔符,而且你不能使用带有空格的文件名。你可以通过在for循环中设置delims和usebackq选项来解决这些问题。 - indiv
对我来说有效,但是我必须添加"delims="才能一起打印出带有空格的完整文件夹名称。 - GChuf

6

5

powershell Get-Content file.txt -Head 1

这个比上面其他 PowerShell 示例要快得多,它只读取文件的一部分。


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

一行代码,与stdout重定向有用的">":

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

3

试试这个

@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

2

以下是使用 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")

为了测试,创建一个文本文件 test.txt,至少有几行内容,并在同一文件夹中运行以下批处理文件(将文件命名为 .bat 扩展名):

@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

在打开的命令提示符窗口中,假设test.txt的第一行内容为line 1,你将会看到:
Hello
line 1
End
Press any key to continue . . .

PowerShell非常慢。 - Anic17
@CyclingDave 我不知道你是怎么测试的,但在 Windows 11 下它对我有效。请查看我在答案中添加的测试。 - mmj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接