答案应该很简单:
findstr /lvg:"fileB.txt" "fileA.txt" >fileC.txt
以您的示例为例,上述内容确实给出了正确的结果。
但是有一个讨厌的 FINDSTR 错误,当使用多个区分大小写的文字搜索字符串时,它会变得不可靠。请参阅为什么这个具有多个文字搜索字符串的 FINDSTR 示例找不到匹配项?,以及随之而来的答案。有关未记录的 FINDSTR 功能和错误的“完整”列表,请参阅Windows FINDSTR 命令的未记录功能和限制是什么?.
因此,上面的简单代码可能会根据文件的内容而失败。如果您可以避免使用不区分大小写的搜索,那么解决方案很简单。
findstr /livg:"fileB.txt" "fileA.txt" >fileC.txt
编辑: 如果 fileB.txt 包含\\
或. 以上两个版本都将失败\"
。为了正常工作,必须将这些字符串转义为\\\
和\\"
但是,如果您必须使用区分大小写的搜索,那么没有简单的解决方案。对于纯批处理解决方案,您最好的选择可能是使用 /R 正则表达式选项。但随后您将不得不创建 fileB.txt 的修改版本,其中所有正则表达式元字符都被转义,以便字符串提供正确的文字搜索。这本身就是一个迷你项目。
对于区分大小写的解决方案,您最好的选择可能是获取第 3 方工具,例如 Windows 的 grep 或 sed。
编辑:这是一个执行合理的纯批处理解决方案,几乎是防弹的
我考虑做类似你问题中提出的逻辑的事情。但是使用批处理读取文件中的所有行相对较慢。此解决方案仅逐行读取排除文件。它使用 FINDSTR 重复读取“fileA.txt”中的行,每个搜索字符串一次。对于批处理文件,这是一种更快的算法。
读取文件的传统方法是使用 FOR /F 循环,但是使用 SET /P 的另一种技术更快,并且可以安全地使用延迟扩展。此方法的唯一限制是:
- 它从行中去除尾随控制字符
- 每行限制为 1021 字节
- 每一行都必须按照
<CR><LF>
Windows 标准终止。它不适用于以<LF>
当与/C 选项一起使用时,搜索字符串必须包含 each\
和"
转义。\\
\"
@echo off
setlocal enableDelayedExpansion
copy fileA.txt fileC.txt >nul
for /f %%N in ('find /c /v "" ^<fileB.txt') do set len=%%N
<fileB.txt (
for /l %%N in (1 1 !len!) do (
set "ln="
set /p "ln="
if defined ln (
set "ln=!ln:\=\\!"
set ln=!ln:"=\"!
move /y fileC.txt temp.txt >nul
findstr /lv /c:"!ln!" temp.txt >fileC.txt
)
)
)
del temp.txt
type fileC.txt