如何创建一个批处理文件,告诉我文本文件的哪些行不在另一个文件中?

时间:2015-07-14 16:14:15

标签: windows batch-file findstr

我要做的是将带有一串字符串的文本文件进行搜索,每个文件都在自己的行上,并在文件中搜索这些字符串中的每一个(check.txt)。我希望输出是一个文本文件,其中包含可能找不到的所有字符串的列表。 到目前为止我已经尝试了一些东西。

 for /F "tokens=*" %%A in search.txt do (
@echo on
FINDSTR %%A check.txt
IF ERRORLEVEL 1 echo %%A FAIL > fail_match.txt
)

我做的另一次尝试(这只是告诉我整个清单是否合适)是

@echo on
FINDSTR /g:search.txt check.txt > a_match.txt 
IF ERRORLEVEL 1 echo bad > a_match.txt

我意识到这些是非常基本的,我确信有一些简单的答案,我只是不明白。我不是程序员;我只是想让我的工作变得更轻松(也更快)。

为了澄清,我要搜索的内容列表在search.txt中,我检查它们的列表是check.txt。 Check.txt是一个json文件,所以它是一条巨大的线。我不知道这是否会有所作为。我想要一个search.txt中不在check.txt中的所有行的列表。

2 个答案:

答案 0 :(得分:1)

您的搜索方案在两个方面看起来很幼稚:

1)JSON不保证是单行。有效的JASON可能有任何数量的空白,包括换行符。如果您的搜索字符串在多行中逻辑匹配,则可能会出现问题。

2)子串匹配怎么样?假设一个搜索字符串为bat,并且您的JSON包含bath。我怀疑你会不会考虑那场比赛。

上述两种问题都可能是您的问题所在。假设它们不是,那么使用FINDSTR可能会有一个相当简单的解决方案。

你第一次尝试就接近了,除了

A) - 您的FOR / F IN()子句缺少括号

B) - 您希望强制每个搜索字符串被解释为字符串文字,可能包含空格。这需要/C:选项。

C) - 您假设搜索字符串中的前导空格不重要("tokens=*"剥离前导空格)

D) - 假设没有搜索行以分号开头。 (默认的EOF字符是分号,FOR / F跳过所有以EOF字符开头的行)

E) - 必须在搜索字符串中转义引号和反斜杠:
\" -> \\\\\"\ -> \\" -> \"。有关详细信息,请参阅What are the undocumented features and limitations of the Windows FINDSTR command?

点C)和D)可以通过使用以下奇怪的语法禁用EOF和DELIMS来修复:

for delims^=^ eof^= %%A in ...

E点)可以通过定义变量并通过搜索和替换添加转义序列来解决。但这需要延迟扩展,但延迟扩展将在扩展时损坏FOR / F变量,如果它们包含!。因此,必须在循环内战略性地切换延迟扩展。

如果上一个命令失败,您可以使用条件命令连接IF ERRORLEVEN n来代替使用||

您不需要查看FINDSTR命令的输出,因此可以重定向到NUL。

您可以通过在循环外重定向一次来提高性能。

@echo off
setlocal disableDelayedExpansion
>fail_match.txt (
  for /f delims^=^ eol^= %%A in (search.txt) do (
    set "search=%%A"
    setlocal enableDelayedExpansion
    set "search2=!search:\"=\\"!"
    set "search2=!search2:\=\\!"
    set "search2=!search2:"=\"!"
    findstr /c:"!search2!" check.txt >nul || echo !search!
    endlocal
  )
)

如果您的搜索字符串都不以;开头,且搜索字符串不包含"\,则解决方案可以简单如下:

@echo off
setlocal disableDelayedExpansion
>fail_match.txt (
  for /f "delims=" %%A in (search.txt) do findstr /c:"%%A" check.txt >nul || echo %%A
)

答案 1 :(得分:0)

如果我正确地读出你的问题(输出不在search.txt中的所有check.txt行),这一行应该这样做:

findstr /v /x /g:search.txt check.txt > nomatch.txt