0

我正在尝试创建一个批处理,该批处理创建一个包含 fileA.txt 中所有行的 fileC.txt,除了那些包含 fileB.txt 中行中的字符串的行:

伪:

foreach(line L in fileA.txt)
     excluded = false
     foreach(string str in fileB.txt)
          if L contains str 
               exclude = true
     if !excluded
          add L to fileC.txt

如果 L ! 包含

例如

fileA.txt:(全部)

this\here\is\a\line.wav
and\this\is\another.wav
i\am\a\chocolate.wav
peanut\butter\jelly\time.wav

fileB.txt:(那些被排除在外的)

another.wav
time.wav

fileC.txt:(想要的结果)

this\here\is\a\line.wav
i\am\a\chocolate.wav

我一直在摆弄 FINDSTR,但我似乎无法将它拼凑在一起.. 任何帮助或指点都非常感谢!

干杯! / 弗莱德

4

1 回答 1

2

答案应该很简单:

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
于 2012-05-07T22:18:11.973 回答