简体   繁体   中英

How can I make a batch file that will tell me which lines of a text file are NOT in another file?

What I'm trying to do is take a text file with a bunch of strings to search for, each on its own line, and search for each one of these strings in a file (check.txt). I want the output to be a text file with a list of all the strings that COULDN'T be found. I've tried a few things so far.

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

Another attempt I made (this one was just to tell me if the whole list was good or not) was

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

I realize that these are incredibly basic, and I'm sure there's some easy answer that I just don't understand. I'm not a programmer; I just want to make my job a lot easier (and faster).

To clarify, my list of things to search for is in search.txt, my list of things to check them against is check.txt. Check.txt is a json file, so it's all one enormous line. I don't know if that will make a difference or not. I want a list of all lines in search.txt that are not in check.txt.

Your search scheme seems naive on two fronts:

1) JSON is not guaranteed to be a single line. A valid JASON may have any amount of whitespace, including newlines. This could cause problems if your search string logically matches across multiple lines.

2) What about substring matches? Suppose one search string is bat , and your JSON contains bath . I doubt you would want to consider that a match.

It is possible that neither of the above concerns are a problem for your case. Assuming they aren't, then there may be a fairly simple solution using FINDSTR.

You were close on your first try, except

A) - Your FOR /F IN() clause is missing parentheses

B) - You want to force each search string to be interpreted as a string literal, possibly with spaces. That requires the /C: option.

C) - You assume leading spaces are not significant in your search string ( "tokens=*" strips leading spaces)

D) - You assume no search lines begin with semicolon. (The default EOF character is semicolon, and FOR /F skips all lines that begin with the EOF character)

E) - Quotes and backslashes must be escaped within a search string:
\\" -> \\\\\\\\\\" , \\ -> \\\\ , " -> \\" . See What are the undocumented features and limitations of the Windows FINDSTR command? for more information.

Points C) and D) may be fixed by disabling EOF and DELIMS using the following odd syntax:

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

Point E) can be addressed by defining a variable and adding escape sequences via search and replace. But this requires delayed expansion, but delayed expansion will corrupt FOR /F variables upon expansion if they contain ! . So delayed expansion must be strategically toggled on and off within the loop.

Instead of using IF ERRORLEVEN n , you can use conditional command concatenation || to take action if the previous command failed.

You don't need to see the output of the FINDSTR command, so that can be redirected to NUL.

You can improve performance by redirecting just once, outside the loop.

@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
  )
)

If none of your search strings begin with ; , and no search string contains " or \\ , then the solution can be as simple as:

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

如果我没看错你的问题(输出不在search.txt中的check.txt的所有行),那么这一行应该可以:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM