Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 批处理:根据(fileA.txt减去fileB.txt)的结果创建fileC.txt_Windows_Batch File_Foreach - Fatal编程技术网

Windows 批处理:根据(fileA.txt减去fileB.txt)的结果创建fileC.txt

Windows 批处理:根据(fileA.txt减去fileB.txt)的结果创建fileC.txt,windows,batch-file,foreach,Windows,Batch File,Foreach,我正在尝试创建一个批处理,该批处理创建一个fileC.txt,其中包含fileA.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

我正在尝试创建一个批处理,该批处理创建一个fileC.txt,其中包含fileA.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
如果我!包含

比如说

fileA.txt:(全部)

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

fileC.txt:(想要的结果)

我一直在摆弄FINDSTR,但我似乎无法把它拼在一起。。非常感谢任何帮助或指点

干杯!
/Fredde

答案应该很简单:

findstr /lvg:"fileB.txt" "fileA.txt" >fileC.txt
就你的例子来说,上面给出了正确的结果

但在使用多个区分大小写的文本搜索字符串时,有一个令人讨厌的FINDSTR bug使得它不可靠。看,以及随之而来的答案。有关未记录的FINDSTR功能和bug的“完整”列表,请参阅

因此,根据文件的内容,上面的简单代码可能会失败。如果可以使用不区分大小写的搜索,那么解决方案很简单

findstr /livg:"fileB.txt" "fileA.txt" >fileC.txt
编辑:如果fileB.txt包含
\\
\“
,上述两个版本都将失败。为了正常工作,必须将这些字符串转义为
\\\\
\”

但如果必须使用区分大小写的搜索,那么就没有简单的解决方案。纯批处理解决方案的最佳选择可能是使用/R正则表达式选项。但是,您必须创建一个fileB.txt的修改版本,其中所有regex元字符都将转义,以便字符串提供正确的文本搜索。这本身就是一个小型项目

对于区分大小写的解决方案,您最好的选择可能是使用第三方工具,如grep或sed for Windows

编辑:这是一个性能合理的纯批量解决方案,几乎是防弹的

我考虑过做一些类似于你问题中提出的逻辑的事情。但使用批处理读取文件中的所有行相对较慢。此解决方案仅逐行读取排除文件。它使用FINDSTR重复读取“fileA.txt”中的行,每个搜索字符串读取一次。对于批处理文件,这是一种更快的算法

读取文件的传统方法是使用FOR/F循环,但还有另一种使用SET/p的技术速度更快,并且可以安全地使用延迟扩展。此方法的唯一限制是:

  • 它将从行中删除尾随的控制字符
  • 它限制为每行1021字节
  • 按照Windows标准,每行必须以
    结尾。它不适用于以
与/C选项一起使用时,搜索字符串必须将每个
\
转义为
\
\”

@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
@echo关闭
setlocal enableDelayedExpansion
复制fileA.txt fileC.txt>nul

对于('find/c/v“^中的/f%%N('find/c/v“^非常详细和令人满意的答案!即使你的第一个解决方案对我来说已经足够了*我非常喜欢阅读你的整个帖子!如果我可以,我会投票给它!我向你鞠躬,哦,明智的德本汉姆!谢谢:)*双关语
findstr /lvg:"fileB.txt" "fileA.txt" >fileC.txt
findstr /livg:"fileB.txt" "fileA.txt" >fileC.txt
@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