【发布时间】:2018-07-29 01:54:55
【问题描述】:
因此,我不知道如何从 *.txt 文本文件中一次一个地获取 CMD 回显行,并稍加延迟以使其看起来像是在处理中。
这甚至可以单独使用批次吗?
我尝试过进行研究,但找不到足够的文本操作来执行此操作,但我确实知道如何在每个命令之间暂停以及如何执行循环。
【问题讨论】:
标签: batch-file cmd
因此,我不知道如何从 *.txt 文本文件中一次一个地获取 CMD 回显行,并稍加延迟以使其看起来像是在处理中。
这甚至可以单独使用批次吗?
我尝试过进行研究,但找不到足够的文本操作来执行此操作,但我确实知道如何在每个命令之间暂停以及如何执行循环。
【问题讨论】:
标签: batch-file cmd
让我们假设文本文件TestFile.txt 应该逐行输出,这是一个 ANSI 编码的文本文件,仅包含包含此文本的 ASCII 字符:
Line 1 is with nothing special. Next line 2 is an empty line.
;Line 3 with a semicolon at beginning.
Line 4 has leading spaces.
Line 5 has a leading horizontal tab.
Line 6 is with nothing special. Next line 7 has just a tab and four spaces if used internet browser does not remove them.
Line 8 is ! with exclamation marks ! in line!
? Line 9 starts with a question mark.
: Line 10 starts with a colon.
] Line 11 starts with a closing square bracket.
下面的批处理文件逐行输出此文本文件,每行之间延迟一秒,但第二行完全为空。
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F "usebackq eol=¿ delims=" %%I in ("TestFile.txt") do (
echo(%%I
%DelayCommand% >nul
)
endlocal
pause
eol= 后面的奇怪字符¿ 是一个反问号,十六进制 Unicode 值 00BF 用于正确输出第三行。由于重新定义了行尾字符,因此不会输出开头带有反问号的行。
此批处理文件代码并非旨在输出具有任何类型的 character encoding 的任何类型的文本文件,而与包含文本文件的字符无关。 Windows 命令行环境不是为输出任何文本文件而设计的。
也可以使用不带引号的不同语法来指定 FOR 选项 delims、eol 和 usebackq 来定义一个空的分隔符列表和 没有行尾字符:
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F usebackq^ delims^=^ eol^= %%I in ("TestFile.txt") do (
echo(%%I
%DelayCommand% >nul
)
endlocal
pause
感谢 aschipfl 提供三个 FOR 选项的替代语法,使用转义字符 ^ 转义非双引号选项字符串中的等号和空格以由 @ 解释987654334@ 字符串usebackq delims= eol= 作为for /F 的一个 参数字符串。
有(,而不是通常用于输出正确的第7行的空格,只有一个制表符和一些普通空格。另请参阅 DosTips 论坛主题 ECHO. FAILS to give text or blank line - Instead use ECHO/。 echo/%%I 不纠正以问号开头的第 9 行输出。
无法使用 FOR 不忽略空行的选项进行定义。但是可以使用 FIND 或 FINDSTR 输出一个文本文件,其中所有行都以行号开头,因此不再有空行。行号括在方括号 (FIND) 中或用冒号 (FINDSTR) 与行的其余部分分隔。可以仅将] 或: 的第一个sequence 之后的字符串分配给循环变量,这在大多数情况下表示文本文件中的整行。但如果文本文件中的一行偶然以] 或: 开头,FOR 也会删除此分隔符。解决方案是这段代码:
@echo off
title Read line by line with delay
setlocal EnableExtensions DisableDelayedExpansion
rem Use command TIMEOUT by default for 1 second delay. But use
rem PING in case of TIMEOUT does not exist as on Windows XP.
set "DelayCommand=%SystemRoot%\System32\timeout.exe /T 1 /NOBREAK"
if not exist %SystemRoot%\System32\timeout.exe set "DelayCommand=%SystemRoot%\System32\ping.exe 127.0.0.1 -n 2"
for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "TestFile.txt" 2^>nul') do (
set "Line=%%I"
setlocal EnableDelayedExpansion
echo(!Line:*:=!
endlocal
%DelayCommand% >nul
)
endlocal
pause
由 FINDSTR 在单独的命令进程中执行的带有行号和冒号的整行输出由 FOR 使用%ComSpec% /c 和' 中的命令行作为额外的参数被分配给循环变量I,它被分配在环境变量Line旁边。
然后根据需要为下一行启用延迟扩展,从而在创建当前环境变量的副本之前将当前环境变量列表的地址以及当前目录路径、命令扩展的状态和延迟扩展的状态推送到堆栈上列表。
接下来将输出环境变量Line 的值,但是将直到第一个冒号的所有内容都替换为任何内容,这会导致实际行的输出存储在没有行号的文本文件中以及由 FINDSTR 在开头插入的冒号。
最后将创建的环境变量列表副本从内存中删除,并将之前的延迟扩展和命令扩展状态从堆栈中弹出并设置,并将当前目录路径再次设置为当前目录和环境变量的先前地址list 被恢复以恢复环境变量列表。
为文本文件中的每一行运行命令setlocal EnableDelayedExpansion 和endlocal 当然效率不高正确分配给环境变量Line,然后处理下一个更正Line 的值。由于每条线路的输出之间存在一秒钟的延迟,因此效率损失在这里并不是真正的问题。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
echo /?endlocal /?findstr /?for /?if /?ping /?rem /?set /?setlocal /?【讨论】:
echo( 而不是echo/(想象一行包含?)。而且我不会在批处理文件中使用(不可见的)控制字符,例如换页符;你可以在这里使用不带引号的语法for /F usebackq^ delims^=^ eol^= %%A。无论如何,你到底为什么要回答这个离题的问题?
尽管您的问题离题了,但我决定将其包含在内,因为已经有两个答案,并且可以使用一行来实现。
来自批处理文件:
@For /F Tokens^=1*Delims^=]^ EOL^= %%A In ('Find /N /V ""^<"C:\test.txt"') Do @Echo(%%B&>Nul PathPing 127.0.0.1 -n -q 1 -p 450
从命令提示符:
For /F Tokens^=1*Delims^=]^ EOL^= %A In ('Find /N /V ""^<"C:\test.txt"') Do @Echo(%B&>Nul PathPing 127.0.0.1 -n -q 1 -p 1350
这两个示例都没有省略源文件中的空行 C:\test.txt,可以根据需要进行更改。
我使用 PathPing 来表示“微小延迟”,因为似乎更可控; 要调整延迟,您只需更改最后一个数字,直到找到最满意的输出。
【讨论】:
] 的第一个 序列 结尾的所有内容。但我想补充一点,在开头有一个或多个] 的行上,此解决方案也不会输出这些右方括号,例如使用findstr /N "^" "C:\Test.txt" 和使用: 作为FOR 中的分隔符忽略后跟冒号的行号,导致在行首不输出冒号。
] 开头的行的可能性远小于空行或以: 开头的行! 事实上,因为字符通常应该关闭前面的[,所以它应该只出现在从固定行长例程输出的行的开头或从使用它的图像输出的行的开头。
: 开头,例如批处理文件或汇编文件。在行首带有右方括号的文本文件非常罕见。在过去 25 年中,我见过的唯一一个以 ] 开头的文本文件是包含 CDATA 部分的 XML 文件,其中嵌入的数据以行结尾结尾。因此,您使用 FIND 的决定绝对是一个非常好的决定,因为它适用于大约 99.99999999% 的所有文本文件,这就是我赞成您的单一命令行解决方案的原因。
]]> 用于关闭 CDATA 部分应位于嵌入数据部分真正结束的 XML 文件中,因为此处结束该部分。通过将]]> 额外放在新行缩进正确意味着将行尾和空格/制表符附加到数据实际上没有的数据部分。根据数据,这可能不是很好。
试试这个批处理脚本:
@echo off
Title Read line by line with delay
set "InputFile=TestFile.txt"
set "delay=1" Rem Delay one seconds, you can change it for your needs
setlocal enabledelayedexpansion
for /f "tokens=*" %%A in ('Type "%InputFile%"') do (
set /a N+=1
set "Line[!N!]=%%A"
)
for /l %%i in (1,1,%N%) do (
echo !Line[%%i]!
Timeout /T %delay% /nobreak>nul
)
pause
【讨论】: