使用批处理删除文件中的部分字符串

use*_*829 3 batch-file findstr

我在文本文件(test.txt)中有一些数据,读取:

wantedunwanteddata
Run Code Online (Sandbox Code Playgroud)

我想删除该字符串中的“不需要的”部分并输出其余部分(即另一个文件(test2.txt)中的“wanteddata”)。我正在使用:

findstr /v "unwanted" test.txt>test2.txt
Run Code Online (Sandbox Code Playgroud)

但是这返回了一个空文件。

J.B*_*oby 6

findstr /v "unwanted" test.txt>test2.txt不起作用的原因是因为findstr搜索与您提供的条件匹配的findstr不会返回匹配条件的子字符串,而是返回满足条件的整行。在findstr /v "unwanted" test.txt>test2.txt您要求输入的所有行中都test.txt没有“不需要的”。这就是为什么test2.txt是空的:没有这样的行。

在批处理中,您可以使用以下语法替换变量值中所有出现的子字符串:%var:substr=repl%. 这将替换字符串contains 中所有出现的substrwith 。由于删除子字符串类似于用空字符串替换(至少在此上下文中),因此您可以使用删除所有出现的.repl%var%%var:substr=%substr

如果要删除文件中所有出现的子字符串,可以使用变量读取该文件的每一行,for /f并在从中删除子字符串后打印出该变量。请注意,由于我们必须在for /f-block内创建一个变量并在同一块内使用它,因此需要延迟扩展此答案解释了原因)。

@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
Run Code Online (Sandbox Code Playgroud)

我已经在变量中设置了(路径)你的输入文件text1.txt和你的输出文件text2.txt(分别是inputoutput),没有周围的引号(使用变量时会添加引号)。如果需要,这将使更改它们变得更容易。周围的
额外内容仅用于处理输出重定向到输出文件。 如果你不想使用延迟扩展,你可以省略与和替换用里面的。(..)for /f
SetLocal EnableDelayedExpansionEndLocalecho !line:%substr%=!call echo %%line:%substr%=%%for /f

编辑:如果您的输入文件包含特殊字符,如<>()|&%,则必须使用延迟扩展。用中使用的正常变量扩展call echo %%line:%substr%=%%这些特殊字符将与他们的特殊含义由CMD-解释器(被处理<>用于输入或输出重定向例如)和产生意外的结果。
此外,我已经包围了substr变量的分配,但是如果您尝试替换的子字符串包含特殊字符,例如<>()|&%它们中的每一个也必须进行转义才能%substr%按预期工作。您可以使用插入符号对特殊字符进行转义^,但%必须加倍(%%而不是%)的 除外。

EDIT2for /f跳过空行,因此如果想在输出文件中保留这些空行,则需要一些解决方法。在纯批次A共同劈来处理那些是使用findstr /nfind /n与它们的行号前面加上每行(包括空的),同时进料inputfile中的for /f。这当然需要一些额外的处理来处理for /f块内的行号并将它们从 的输出中删除,for /f但这是可能的。这个对类似问题的回答为这些变通方法及其缺点提供了很好的解释。