我从一个数据文件读取多行并将其附加到另一个文件。 问题是在附加行末尾的输出文件中有一些额外的空间。 根据我的要求修改尾部空格是必须的,因为在原始数据文件中,行尾没有空格。 我尝试了所有可能的事情,但是我仍然无法做到这一点。
@echo off setlocal enabledelayedexpansion FOR /F "delims=" %%c IN (C:\Users\184863\Desktop\mydata.txt) DO ( echo %%c>>temp_data.txt ) endlocal
我试过的选项:
echo %%c>>temp_data.txt
…获得1空间行结束
set lines=%%c
echo !lines!>>temp_data.txt
…得到1行结束
echo !lines:~0,-1!>>temp_data.txt
…修剪行的最后一个字符
set lines=!lines: =!
echo !lines!>>temp_data.txt
…行内的所有空格也被修剪(只需要修剪行的末尾,这在原始数据文件中不存在)
你有一个终端空间在echo %%c>>temp_data.txt
(等等)应该被删除。 这是终端空间引起的混乱的典型。
echo
线末尾有尾随空格,因为Magoo已经写过ECHO没有忽略的部分。 在%%c
之后, ECHO也输出这个尾部空格。
重定向通常写在命令行的末尾,但可以在任何地方写入。 也可以在下面或者中间的某个地方写入重定向,就像在这个答案的 FOR命令行中可以看到的一样。 ECHO命令行的解析与所有其他命令行不同,因为双引号字符串之外的空格字符不会被解释为参数分隔符,因此, ECHO命令行中的每个空格字符都很重要,并且由ECHO输出,包括重定向运算符像>
。
这可以很容易地被看到
Test.txt
后面添加一个尾随空格的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/]
[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命令解释程序执行的内容,而不是写入批处理文件中的内容。
此外,延迟的环境变量扩展被启用,导致从Windows命令解释器处理的%%c
引用的文件的行读取!VariableName!
在执行ECHO命令之前。 行中两个感叹号之间的所有内容都被解释为变量名,因此,如果没有这样的环境变量,则分别用引用变量的值替换。 在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
在此批处理代码中,显式禁用延迟的环境变量扩展,以将感叹号始终作为文字字符进行解释。
包含要读取的行的文本文件是使用预定义的Windows环境变量 USERPROFILE
指定的,并用双引号括起来,以便在任何Windows计算机上工作。 双引号需要使用选项usebackq
来获取带有路径的文件名字符串,解释为文本文件名,从中读取行。
作为一条线可能以1到9范围内的数字结尾,这是不好的使用:
echo %%c>>temp_data.txt
最好在ECHO命令行的开头指定重定向操作符,并指定下一个没有尾随空格的echo %%c
。 阅读有关使用命令重定向运算符的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命令行的末尾。
解决方案2:
@echo off copy /B temp_data.txt+"%USERPROFILE%\Desktop\mydata.txt" temp_data.txt >nul
COPY命令可用于将用+
运算符指定的多个文件的内容合并成最后指定的单个文件。 此功能用于在现有的temp_data.txt
追加用户桌面上mydata.txt
的行。 需要选项/B
(二进制数据)以避免COPY附加到输出文件temp_data.txt
^ Z,该文件是具有十六进制代码值1A的替代控制字符SUB 。
这个解决方案肯定比第一个更好,因为它不涉及mydata.txt
包含的文件。
为了理解使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
copy /?
echo /?
endlocal /?
for /?
setlocal /?
这应该是一个简单的修复你。 一:当不需要延迟扩展时,不要使用延迟扩展。二:删除echo命令中的尾随空格。
@( setlocal echo off SET "_File=C:\Users\184863\Desktop\mydata.txt" SET "_Count=0" SET "_Comment=Your Special Comment " ) FOR /F "tokens=* delims=" %%c IN (%_File%) DO ( CALL :CountEcho %%c ) ( endlocal exit /b 0 ) :CountEcho CALL SET /A "_Count=%_Count% + 1" IF /I %_Count% NEQ 100 ( REM Line Not Equal to 100, Comment it ECHO:%_Comment%%*>>"%~dp0temp_data.txt" ) ELSE ( REM Line 100 - No Comment ECHO:%*>>"%~dp0temp_data.txt" ) GOTO :EOF