[英]Why does ECHO command print some extra trailing space into the file?
I am reading multiple lines from a data file and append it to another file.我正在从数据文件中读取多行并将其附加到另一个文件中。 The issue is that some extra space is in output file at end of appended lines.
问题是附加行末尾的输出文件中有一些额外的空间。 It is mandatory to trim the trailing space according to my requirement because in original data file there is no space at end of the lines.
根据我的要求修剪尾随空格是强制性的,因为在原始数据文件中,行尾没有空格。 I tried all possible things, but I still cannot achieve this one.
我尝试了所有可能的事情,但我仍然无法实现这一目标。
@echo off
setlocal enabledelayedexpansion
FOR /F "delims=" %%c IN (C:\Users\184863\Desktop\mydata.txt) DO (
echo %%c>>temp_data.txt
)
endlocal
Options I tried:我试过的选项:
echo %%c>>temp_data.txt
... getting 1 space end of line echo %%c>>temp_data.txt
... 得到 1 个空格的行尾
set lines=%%c
echo !lines!>>temp_data.txt
... getting 1 space end of line echo !lines!>>temp_data.txt
... 得到 1 个空格的行尾
echo !lines:~0,-1!>>temp_data.txt
... last char of the line trimmed echo !lines:~0,-1!>>temp_data.txt
... 行的最后一个字符被修剪
set lines=!lines: =!
echo !lines!>>temp_data.txt
... all spaces inside the line are also trimmed (need to trim only end of the line, which is not present in original data file) echo !lines!>>temp_data.txt
... 行内的所有空格也被修剪(只需要修剪行尾,原始数据文件中不存在)
You have a terminal space on the line echo %%c>>temp_data.txt
(amongst others) which should be deleted.您在
echo %%c>>temp_data.txt
(以及其他)行上有一个终端空间,应该删除它。 This is typical of the confusion that terminal spaces causes.这是终端空间引起的典型混淆。
There is a trailing space at end of the echo
line as Magoo wrote already which is not ignored by ECHO .正如Magoo已经写的那样,在
echo
行的末尾有一个尾随空格,它不会被ECHO忽略。 This trailing space is also output by ECHO after %%c
.这个尾随空格也由ECHO在
%%c
之后输出。
A redirection is usually written at end of a command line, but it can be written anywhere.重定向通常写在命令行的末尾,但也可以写在任何地方。 It is also possible to write the redirection at beginning as shown below or somewhere in the middle as it can be seen on FOR command line in this answer .
也可以在开头编写重定向,如下所示或中间某处,如本答案中的FOR命令行所示。 Parsing of an ECHO command line is different to all other command lines as a space character outside a double quoted string is not interpreted as argument separator and for that reason each space character in ECHO command line matters and is output by ECHO including those before redirection operators like
>
. ECHO命令行的解析与所有其他命令行不同,因为双引号字符串之外的空格字符不会被解释为参数分隔符,因此ECHO命令行中的每个空格字符都很重要并且由ECHO输出,包括重定向运算符之前的那些喜欢
>
。
This can be seen easily by这可以很容易地看出
echo Test>Test.txt
with a trailing space after Test.txt
,echo Test>Test.txt
与后尾空间Test.txt
, Output is echo Test 1>Test.txt
.输出是
echo Test 1>Test.txt
。 So >
is replaced by Windows command interpreter by 1>
(space, one, right angle bracket) and additionally moved to end of line.所以
>
被 Windows 命令解释器替换为1>
(空格,一,右尖括号),并另外移动到行尾。 This movement on ECHO command line results in originally trailing space being moved left after the text Test
and is therefore also output by ECHO . ECHO命令行上的这种移动导致最初的尾随空格在文本
Test
之后向左移动,因此也由ECHO输出。
This command line modification during preprocessing of the entire command block can be seen also by running original posted batch code without @echo off
from within a command prompt window to debug the batch file.在整个命令块预处理期间的命令行修改也可以通过在命令提示符窗口中运行原始发布的批处理代码而不使用
@echo off
来调试批处理文件来查看。 Windows command interpreter outputs with mydata.txt
containing the single line [code=119888#!198; ttps://egrul.nalog.ru/]
Windows 命令解释器输出
mydata.txt
包含单行[code=119888#!198; ttps://egrul.nalog.ru/]
[code=119888#!198; ttps://egrul.nalog.ru/]
: [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
The trailing space after >>temp_data.txt
is now after preprocessing the entire FOR command line with the command block containing only a single command left to 1>>temp_data.txt
. >>temp_data.txt
之后的尾随空格现在是在预处理整个FOR命令行之后,命令块只包含一个命令,剩下的1>>temp_data.txt
。 When FOR executes the ECHO command line, the trailing space being now an additional space between line read from mydata.txt
and 1>>temp_data.txt
is also output by ECHO .当FOR执行ECHO命令行时,尾随空格现在是从
mydata.txt
读取的行和1>>temp_data.txt
之间的附加空格也由ECHO输出。
It should be always taken into account what is really executed by Windows command interpreter after preprocessing/parsing a command line and not what is written in the batch file.在预处理/解析命令行后,应该始终考虑 Windows 命令解释器真正执行的内容,而不是批处理文件中写入的内容。
Furthermore delayed environment variable expansion is enabled which results in line read from the file referenced with %%c
being processed by Windows command interpreter for !VariableName!
此外,还启用了延迟环境变量扩展,这会导致从
%%c
引用的文件中读取行,Windows 命令解释器正在处理!VariableName!
before executing the ECHO command.在执行ECHO命令之前。 Everything between two exclamation marks in line is interpreted as variable name and therefore replaced by value of the referenced variable respectively nothing if there is no such environment variable.
行中两个感叹号之间的所有内容都被解释为变量名,因此如果没有这样的环境变量,则分别替换为引用变量的值。 A single (remaining) exclamation mark is simply removed by Windows command interpreter during this additional processing of the line before ECHO execution.
在ECHO执行之前对行进行额外处理期间,Windows 命令解释器会简单地删除一个(剩余的)感叹号。
Solution 1:解决方案1:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "usebackq delims=" %%I in ("%USERPROFILE%\Desktop\mydata.txt") do >>temp_data.txt echo(%%I
endlocal
Delayed environment variable expansion is explicitly disabled in this batch code to interpret exclamation marks always as literal characters.此批处理代码中明确禁用了延迟环境变量扩展,以将感叹号始终解释为文字字符。
There is used (
instead of a space character between the command echo
and the loop variable reference %%I
to output a line starting with /?
correct instead of the usage help of command ECHO as it would happen on using echo %%I
and a line read from the text file mydata.txt
starts with /?
after 0 or more leading spaces/tabs.使用
(
而不是命令echo
和循环变量引用%%I
之间的空格字符来输出以/?
开头的行正确而不是命令ECHO的使用帮助,因为它会发生在使用echo %%I
和 a从文本文件mydata.txt
读取的行在 0 个或多个前导空格/制表符后以/?
开头。
The text file with the line(s) to read is specified using predefined Windows environment variable USERPROFILE
enclosed in double quotes to work on any Windows computer.包含要读取的行的文本文件使用双引号括起来的预定义Windows 环境变量
USERPROFILE
指定,以便在任何 Windows 计算机上工作。 The double quotes require the option usebackq
to get the file name string with path interpreted as text file name from which to read lines.双引号需要选项
usebackq
来获取文件名字符串,其中路径解释为要从中读取行的文本文件名。
As a line perhaps ends with a number in range 0 to 9 it is not good to use:由于一行可能以 0 到 9 范围内的数字结尾,因此不适合使用:
echo %%c>>temp_data.txt
It is better to specify the redirection operator at beginning of the ECHO command line and specify next the echo %%c
with no trailing space.最好在ECHO命令行的开头指定重定向运算符,然后指定没有尾随空格的
echo %%c
。 Please read the Microsoft documentation about Using command redirection operator for more information.请阅读有关使用命令重定向运算符的 Microsoft 文档以获取更多信息。
Please note that FOR ignores empty lines and also all lines starting with a semicolon with the used options.请注意FOR 会忽略空行以及所有以分号开头的行,并带有所使用的选项。
;
is the default for option eol
(end of line) which is not explicitly specified in this batch file.是此批处理文件中未明确指定的选项
eol
(行尾)的默认值。
On running this small batch file with @echo off
modified to @echo ON
from within a command prompt window instead of double clicking on it, it can be seen what Windows command interpreter really executes:在运行这个小批处理文件时,@
@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
So it can be seen which command line is finally executed by Windows command interpreter after preprocessing each command line of the batch file before execution.所以在执行前对批处理文件的每个命令行进行预处理后,可以看出Windows命令解释器最终执行的是哪个命令行。
>>
was replaced by 1>>
(note inserted space at beginning) and the redirection at beginning was moved to end of ECHO command line. >>
被1>>
替换(注意在开头插入空格)并且开头的重定向被移动到ECHO命令行的末尾。
Another solution is enclosing the command ECHO in round brackets to form a command block and redirect the output of this command block with just command ECHO to a file, ie use (echo %%c) >>temp_data.txt
.另一种解决方案是在圆括号包围命令ECHO以形成命令块和只用命令ECHO该命令块的输出重定向到一个文件,即使用
(echo %%c) >>temp_data.txt
。 The number of spaces after )
do not matter anymore. )
之后的空格数不再重要。 Therefore (echo %%c)>> temp_data.txt
with a space after redirection operator >>
and a trailing space at line end results in same text in file temp_data.txt
as on using >>temp_data.txt echo %%c
.因此,
(echo %%c)>> temp_data.txt
在重定向操作符之后带有空格>>
和行尾的尾随空格导致文件temp_data.txt
文本与使用>>temp_data.txt echo %%c
。
Solution 2:解决方案2:
@echo off
copy /B temp_data.txt+"%USERPROFILE%\Desktop\mydata.txt" temp_data.txt >nul
The COPY command can be use to merge contents of multiple files specified with +
operator together into a single file specified last. COPY命令可用于将用
+
运算符指定的多个文件的内容合并到最后指定的单个文件中。 This feature is used here to append to existing temp_data.txt
the lines from mydata.txt
on the user´s desktop.此处使用此功能将用户桌面上
mydata.txt
的行附加到现有temp_data.txt
。 The option /B
(binary data) is needed to avoid that COPY appends to output file temp_data.txt
^Z which is the substitute control character SUB with hexadecimal code value 1A.需要选项
/B
(二进制数据)以避免COPY附加到输出文件temp_data.txt
^Z,它是十六进制代码值 1A 的替代控制字符SUB 。
This solution is definitely better than the first one as it does not matter what the file mydata.txt
contains.这个解决方案肯定比第一个更好,因为文件
mydata.txt
包含什么无关紧要。
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.要了解使用的命令及其工作原理,请打开命令提示符窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
copy /?
echo /?
endlocal /?
for /?
setlocal /?
This should do the needful, including the need to comment line 100.这应该是必要的,包括需要注释第 100 行。
One: Don't use delayed expansion when it isn't necessary.一:没有必要时不要使用延迟扩展。
Two: Remove the trailing space in your echo command.二:删除 echo 命令中的尾随空格。
@(
SETLOCAL
ECHO OFF
SET "_File=C:\Users\184863\Desktop\mydata.txt"
SET "_Count="
SET "_Comment=Your Special Comment "
)
FOR /F "tokens=* delims=" %%c IN (%_File%) DO (
SET /A "Count+=1">NUL
CALL ECHO.[%COUNT%] | FIND "[100]">NUL && (
ECHO:%_Comment%%~c
) || (
ECHO.%%c
)
)>>"%~dp0temp_data.txt"
REM Replace the original file with the commented File
MOVE /Y "%~dp0temp_data.txt" "%_File%"
(
ENDLOCAL
EXIT /B 0
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.