echo 行的末尾有一个尾随空格,正如Magoo 已经写的那样,ECHO 不会忽略它。这个尾随空格也是由 ECHO 在%%c 之后输出的。
重定向通常写在命令行的末尾,但它可以写在任何地方。也可以在开头编写重定向,如下所示或在中间某处,如在this answer 中的FOR 命令行中可以看到的那样。 ECHO 命令行的解析与所有其他命令行不同,因为双引号字符串之外的空格字符不会被解释为参数分隔符,因此 ECHO中的每个空格字符> 命令行很重要,由 ECHO 输出,包括> 等重定向运算符之前的命令行。
这很容易被看到
- 创建一个只包含
echo Test>Test.txt 的批处理文件,Test.txt 后面有一个空格,
- 打开命令提示符窗口,然后
- 在命令提示符窗口中运行此批处理文件。
输出为echo Test 1>Test.txt。所以> 被Windows 命令解释器替换为 1>(空格,一,右尖括号),并另外移动到行尾。 ECHO 命令行上的这种移动会导致最初的尾随空格在文本 Test 之后向左移动,因此也由 ECHO 输出。
在整个命令块预处理期间的命令行修改也可以通过在命令提示符窗口中运行不带@echo off 的原始发布的批处理代码来调试批处理文件。 Windows 命令解释器输出 mydata.txt 包含单行 [code=119888#!198; ttps://egrul.nalog.ru/]:
setlocal enabledelayedexpansion
FOR /F "delims=" %c IN (C:\Users\184863\Desktop\mydata.txt) DO (echo %c 1>>temp_data.txt )
(echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt )
endlocal
>>temp_data.txt 之后的尾随空格现在是在预处理整个 FOR 命令行之后,该命令块只包含一个命令,留给 1>>temp_data.txt。当 FOR 执行 ECHO 命令行时,尾随空格现在是从 mydata.txt 和 1>>temp_data.txt 读取的行之间的附加空格,ECHO。
应始终考虑在预处理/解析命令行后由 Windows 命令解释器实际执行的内容,而不是批处理文件中写入的内容。
启用了进一步延迟的环境变量扩展,这会导致在执行 ECHO 命令之前,Windows 命令解释器会为 !VariableName! 处理从 %%c 引用的文件中读取的行。行中两个感叹号之间的所有内容都被解释为变量名,因此如果没有这样的环境变量,则分别替换为引用变量的值。在执行 ECHO 之前,在对行进行额外处理期间,Windows 命令解释器会简单地删除一个(剩余的)感叹号。
解决方案 1:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "usebackq delims=" %%I in ("%USERPROFILE%\Desktop\mydata.txt") do >>temp_data.txt echo(%%I
endlocal
在此批处理代码中明确禁用延迟的环境变量扩展,以将感叹号始终解释为文字字符。
在命令echo和循环变量引用%%I之间使用(代替空格字符来输出以/?开头的行正确而不是命令的使用帮助ECHO 就像使用 echo %%I 和从文本文件 mydata.txt 读取的行在 0 个或多个前导空格/制表符之后以 /? 开头一样。
带有要读取的行的文本文件是使用预定义的Windows environment variableUSERPROFILE 括在双引号中指定的,以便在任何Windows 计算机上工作。双引号需要选项 usebackq 来获取文件名字符串,路径被解释为要从中读取行的文本文件名。
由于一行可能以 0 到 9 范围内的数字结尾,所以不好使用:
echo %%c>>temp_data.txt
最好在 ECHO 命令行的开头指定重定向运算符,然后在后面指定echo %%c,不带空格。请阅读有关 Using command redirection operator 的 Microsoft 文档以了解更多信息。
请注意,FOR 会忽略空行以及所有以分号开头并带有所用选项的行。 ; 是选项 eol(行尾)的默认值,此批处理文件中未明确指定。
在将@echo off 修改为@echo ON 从命令提示符窗口中运行这个小批处理文件而不是双击它时,可以看到Windows 命令解释器真正执行的是什么:
for /F "usebackq delims=" %I in ("C:\Users\184863\Desktop\mydata.txt") do echo %I 1>>temp_data.txt
echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt
所以在执行前对批处理文件的每个命令行进行预处理后,可以看出Windows命令解释器最终执行的是哪个命令行。 >> 被 1>> 替换(注意开头插入空格),开头的重定向被移到 ECHO 命令行的末尾。
另一种解决方案是将命令 ECHO 括在圆括号中以形成命令块,并仅使用命令 ECHO 将该命令块的输出重定向到文件,即使用(echo %%c) >>temp_data.txt。 ) 之后的空格数不再重要。因此,(echo %%c)>> temp_data.txt 在重定向运算符 >> 之后带有一个空格,并且在行尾有一个尾随空格,导致文件 temp_data.txt 中的文本与使用 >>temp_data.txt echo %%c 时相同。
解决方案 2:
@echo off
copy /B temp_data.txt+"%USERPROFILE%\Desktop\mydata.txt" temp_data.txt >nul
COPY 命令可用于将使用+ 运算符指定的多个文件的内容合并到最后指定的单个文件中。此处使用此功能将来自用户桌面上mydata.txt 的行附加到现有的temp_data.txt。需要选项 /B(二进制数据)以避免 COPY 附加到输出文件 temp_data.txt ^Z,它是具有十六进制代码值 1A 的替换控制字符 SUB。
这个解决方案肯定比第一个更好,因为文件mydata.txt 包含什么并不重要。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
copy /?
echo /?
endlocal /?
for /?
setlocal /?