如何使用Windows批处理文件遍历文本文件中的每一行?

Mr.*_*aus 228 windows batch-file

我想知道如何使用Windows批处理文件遍历文本文件中的每一行,并连续处理每行文本.

Mr.*_*aus 283

下面的帖子有很大帮助,但没有按照我在问题中所说的那样做,我需要处理整个整行.这是我发现的工作方式.

for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Run Code Online (Sandbox Code Playgroud)

带有星号(*)的标记关键字将拉出整行的所有文本.如果你没有放入星号,它只会拉出该行的第一个单词.我认为它与空间有关.

对于TechNet上的命令

我感谢所有的帖子!


如果文件路径中有空格,则需要使用usebackq.例如.

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
Run Code Online (Sandbox Code Playgroud)

  • 一个小小的补充:要以交互方式从命令行开始工作,请在上面的命令中将`%% A`替换为'%A`.否则你会得到'%% A此时出乎意料. (31认同)
  • 仅供参考,如果你需要做一个多行命令,在"DO"之后你可以放一个左括号"("和几行后面,用一个紧密的括号结尾")" - 你可以放你的代码阻止那些(缩减你的口味). (16认同)
  • 谢谢你的模式.我发现我不能在文件名周围加上引号(") - 对于带空格的文件名只给我文件名.例如`for/F"tokens =*"%% A in("myfile. txt")做回声A = %% A` - >`A = myfile.txt`.有什么想法如何阻挠这个? (3认同)
  • 值得指出的是,循环中的索引参数必须是单个字符。例如 %%i 没问题,但 %%index 会失败。 (3认同)
  • 确保您使用的文件以 ANSI 或 UTF8 编码。在我尝试使用 TYPE 命令查看文件并且输出不是我所期望的之前,我一直在思考为什么这不起作用。此时我注意到由于某种原因该文件已被编码为“UCS-2 BE BOM”! (2认同)

Ash*_*Ash 54

从Windows命令行参考:

要解析文件,忽略注释行,请键入:

for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k
Run Code Online (Sandbox Code Playgroud)

此命令解析Myfile.txt中的每一行,忽略以分号开头的行,并将第二个和第三个标记从每个行传递给FOR主体(标记由逗号或空格分隔).FOR语句的主体引用%i来获取第二个标记,%j来获取第三个标记,%k来获取所有剩余的标记.

如果您提供的文件名包含空格,请在文本周围使用引号(例如,"文件名").要使用引号,必须使用usebackq.否则,引号将被解释为定义要解析的文字字符串.

顺便说一句,您可以在大多数Windows系统上找到命令行帮助文件:

 "C:\WINDOWS\Help\ntcmds.chm"
Run Code Online (Sandbox Code Playgroud)

  • 要[澄清](http://ss64.com/nt/for_cmd.html)_"要使用引号,你必须使用`usebackq`"_:`for/f"usebackq"%% a in("Z :\ My Path包含Spaces\xyz\abc.txt")` (7认同)
  • 很好的解释. (2认同)

小智 31

在批处理文件中,您必须使用%%而不是%:(类型help for)

for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF
Run Code Online (Sandbox Code Playgroud)

这样做:for命令末尾的"do call:process %% i %% j %% k"将forfile命令中获取的信息从myfile.txt传递给"process"'子例程'.

在批处理程序中使用for命令时,需要对变量使用双%符号.

以下行将那些变量从for命令传递给进程'sub routine',并允许您处理此信息.

set VAR1=%1
 set VAR2=%2
 set VAR3=%3
Run Code Online (Sandbox Code Playgroud)

如果需要进一步的示例,我对这个确切的设置有一些非常高级的用法,我愿意分享.当然,根据需要添加您的EOL或Delims.


Yog*_*jan 26

改进第一个"FOR/F .."答案:我必须做的是调用执行MyList.txt中列出的每个脚本,所以它对我有用:

for /F "tokens=*" %A in  (MyList.txt) do CALL %A ARG1
Run Code Online (Sandbox Code Playgroud)

- 或者,如果您希望通过多行执行此操作:

for /F "tokens=*" %A in  (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
Run Code Online (Sandbox Code Playgroud)

编辑:上面给出的例子是从命令提示符执行FOR循环; 从批处理脚本中,需要添加额外的%,如下所示:

---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in  ( MyList.TXT) do  (
   ECHO Processing %%A.... 
   CALL %%A ARG1 
)
@echo on
;---END of MyScript.bat---
Run Code Online (Sandbox Code Playgroud)


Mar*_*ane 21

@ MrKraus的回答很有启发性.此外,让我补充一点,如果要加载与批处理文件位于同一目录中的文件,请在文件名前加上%~dp0.这是一个例子:

cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Run Code Online (Sandbox Code Playgroud)

注意::如果您的文件名或目录(例如上例中的myfile.txt)有空格(例如'my file.txt'或'c:\ Program Files'),请使用:

for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
Run Code Online (Sandbox Code Playgroud)

,使用type关键字调用type程序,该程序显示文本文件的内容.如果您不想承受调用type命令的开销,则应将目录更改为文本文件的目录.请注意,带空格的文件名仍然需要类型.

我希望这可以帮助别人!

  • 'type` walkaround的Thx和+1 (2认同)

jeb*_*jeb 15

接受的答案是好的,但有两个限制.
它会删除空行和行;

要读取任何内容的行,您需要延迟扩展切换技术.

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo(!var!
    ENDLOCAL
)
Run Code Online (Sandbox Code Playgroud)

Findstr用于为每行添加行号和冒号,因此空行不再为空.

在访问%%a参数时,需要禁用DelayedExpansion ,否则感叹号!和插入符^将丢失,因为它们在该模式下具有特殊含义.

但要从行中删除行号,需要启用延迟扩展.
set "var=!var:*:=!"删除所有直到第一个冒号(使用delims=:也将删除行开头的所有冒号,而不仅是来自findstr的冒号).
endlocal再次禁用下一行的延迟扩展.

唯一的限制是现在线路长度限制为~8191,但似乎没有办法克服这一点.


Pau*_*aul 14

或者,您可以在引号中排除选项:

FOR /F %%i IN (myfile.txt) DO ECHO %%i
Run Code Online (Sandbox Code Playgroud)


小智 9

这是我写的一个bat文件,用于执行文件夹中的所有SQL脚本:

REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************

dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
Run Code Online (Sandbox Code Playgroud)

  • 跳过临时文件,只需使用for/f %% A in('dir/b/o:n*sql')做... (5认同)

miv*_*ivk 6

接受的 anwser 使用cmd.exe

for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
Run Code Online (Sandbox Code Playgroud)

仅适用于“普通”文件。它在巨大的文件中惨遭失败。

对于大文件,您可能需要使用 Powershell 和类似的东西:

[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
Run Code Online (Sandbox Code Playgroud)

或者如果你有足够的内存:

foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" } 
Run Code Online (Sandbox Code Playgroud)

这对我来说适用于包含超过 200 万行的 250 MB 文件,其中for /F ...命令在几千行后卡住了。

对于之间的差异foreachForEach-Object,看到挥笔的ForEach和foreach-对象

(学分:在 PowerShell 中逐行读取文件


Mic*_*tha 5

如果你有一个NT系列Windows(一个cmd.exe作为shell),请尝试FOR/F命令.