使用批处理删除文件中的部分字符串
Remove part of string in file using batch
我在文本文件中有一些数据 (test.txt),阅读:
wantedunwanteddata
我想删除该字符串中的 "unwanted" 部分并输出其余部分(即 "wanteddata" 到另一个文件 (test2.txt)。我正在使用:
findstr /v "unwanted" test.txt>test2.txt
但是这会返回一个空文件。
findstr /v "unwanted" test.txt>test2.txt
不起作用的原因是 findstr
搜索符合您给它的条件的 行。 findstr
不会 return 匹配条件的子字符串,而是满足条件的整行。在 findstr /v "unwanted" test.txt>test2.txt
中,您要求 test.txt
中没有 "unwanted" 的所有行 。这就是 test2.txt
为空的原因:没有这样的行。
在批处理中,您可以使用以下语法替换变量值中出现的所有子字符串:%var:substr=repl%
。这将在 %var%
包含的字符串中用 repl
替换所有出现的 substr
。由于删除子字符串类似于用空字符串替换(至少在这种情况下),您可以使用 %var:substr=%
删除所有出现的 substr
.
如果你想删除文件中所有出现的子字符串,你可以在一个变量中读取该文件的每一行,for /f
and print out that variable after removing the substring from it. Be aware that as we will have to create a variable inside a for /f
-block and use it inside that same block, delayed expansion will be needed (this answer 解释了原因)。
@echo off
SetLocal EnableDelayedExpansion
set input=text1.txt
set output=text2.txt
set "substr=unwanted"
(
FOR /F "usebackq delims=" %%G IN ("%input%") DO (
set line=%%G
echo. !line:%substr%=!
)
) > "%output%"
EndLocal
exit /b 0
我已经在变量(分别为 input
和 output
)中设置了您的输入文件 text1.txt
和输出文件 text2.txt
的(路径),没有引号(引号是使用变量时添加)。如果需要,这将使更改它们变得更容易。
for /f
周围的额外 (..)
仅用于处理到输出文件的输出重定向。
如果您不想使用延迟扩展,可以省略 SetLocal EnableDelayedExpansion
和 EndLocal
并将 echo !line:%substr%=!
替换为 for /f
中的 call echo %%line:%substr%=%%
。
编辑:如果您的输入文件包含特殊字符,如<>()|&%
,您必须使用延迟扩展。使用 call echo %%line:%substr%=%%
中使用的正常变量扩展,这些特殊字符将由 cmd-interpreter 以其特殊含义处理(例如 input or output redirection 的 <
和 >
)并产生意想不到的结果。
此外,我已经包围了 substr
变量的赋值,但是如果您要替换的子字符串包含特殊字符,例如 <>()|&%
,则还必须转义每个字符,以便 %substr%
到按预期工作。您可以使用 caret-sign ^
来转义特殊字符,除了 %
必须加倍(%%
而不是 %
)。
EDIT2:for /f
跳过空行,所以如果想在输出文件中保留这些空行,需要一些解决方法。纯批处理中的一个常见 hack 是使用 findstr /n
或 find /n
在将输入文件提供给 for /f
时在每一行(包括空行)前面加上行号。这当然需要一些额外的处理来处理 for /f
块内的行号并将它们从 for /f
的输出中删除,但这是可能的。 对类似问题提供了对这些解决方法及其缺点的极好解释。
我在文本文件中有一些数据 (test.txt),阅读:
wantedunwanteddata
我想删除该字符串中的 "unwanted" 部分并输出其余部分(即 "wanteddata" 到另一个文件 (test2.txt)。我正在使用:
findstr /v "unwanted" test.txt>test2.txt
但是这会返回一个空文件。
findstr /v "unwanted" test.txt>test2.txt
不起作用的原因是 findstr
搜索符合您给它的条件的 行。 findstr
不会 return 匹配条件的子字符串,而是满足条件的整行。在 findstr /v "unwanted" test.txt>test2.txt
中,您要求 test.txt
中没有 "unwanted" 的所有行 。这就是 test2.txt
为空的原因:没有这样的行。
在批处理中,您可以使用以下语法替换变量值中出现的所有子字符串:%var:substr=repl%
。这将在 %var%
包含的字符串中用 repl
替换所有出现的 substr
。由于删除子字符串类似于用空字符串替换(至少在这种情况下),您可以使用 %var:substr=%
删除所有出现的 substr
.
如果你想删除文件中所有出现的子字符串,你可以在一个变量中读取该文件的每一行,for /f
and print out that variable after removing the substring from it. Be aware that as we will have to create a variable inside a for /f
-block and use it inside that same block, delayed expansion will be needed (this answer 解释了原因)。
@echo off
SetLocal EnableDelayedExpansion
set input=text1.txt
set output=text2.txt
set "substr=unwanted"
(
FOR /F "usebackq delims=" %%G IN ("%input%") DO (
set line=%%G
echo. !line:%substr%=!
)
) > "%output%"
EndLocal
exit /b 0
我已经在变量(分别为 input
和 output
)中设置了您的输入文件 text1.txt
和输出文件 text2.txt
的(路径),没有引号(引号是使用变量时添加)。如果需要,这将使更改它们变得更容易。
for /f
周围的额外 (..)
仅用于处理到输出文件的输出重定向。
如果您不想使用延迟扩展,可以省略 SetLocal EnableDelayedExpansion
和 EndLocal
并将 echo !line:%substr%=!
替换为 for /f
中的 call echo %%line:%substr%=%%
。
编辑:如果您的输入文件包含特殊字符,如<>()|&%
,您必须使用延迟扩展。使用 call echo %%line:%substr%=%%
中使用的正常变量扩展,这些特殊字符将由 cmd-interpreter 以其特殊含义处理(例如 input or output redirection 的 <
和 >
)并产生意想不到的结果。
此外,我已经包围了 substr
变量的赋值,但是如果您要替换的子字符串包含特殊字符,例如 <>()|&%
,则还必须转义每个字符,以便 %substr%
到按预期工作。您可以使用 caret-sign ^
来转义特殊字符,除了 %
必须加倍(%%
而不是 %
)。
EDIT2:for /f
跳过空行,所以如果想在输出文件中保留这些空行,需要一些解决方法。纯批处理中的一个常见 hack 是使用 findstr /n
或 find /n
在将输入文件提供给 for /f
时在每一行(包括空行)前面加上行号。这当然需要一些额外的处理来处理 for /f
块内的行号并将它们从 for /f
的输出中删除,但这是可能的。