2015-07-14 4 views
0

Что я пытаюсь сделать, это взять текстовый файл с кучей строк для поиска, каждый в своей строке, и выполнить поиск каждой из этих строк в файле (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.

ответ

1

Ваша схема поиска кажется наивным на двух фронтах:

1) JSON не гарантированно будет одной линией. Действительный JASON может иметь любое количество пробелов, включая символы новой строки. Это может вызвать проблемы, если ваша строка поиска логически соответствует нескольким строкам.

2) Что относительно подстрочных совпадений? Предположим, что одна строка поиска - bat, а ваш JSON содержит bath. Я сомневаюсь, что вы захотите рассмотреть этот матч.

Возможно, что ни одна из вышеуказанных проблем не является проблемой для вашего случая. Предполагая, что это не так, тогда с помощью FINDSTR может быть довольно простое решение.

Вы были близки с первой попытки, кроме

A) - Ваш FOR/F IN() оговорка отсутствует Скобки

B) - Вы хотите, чтобы заставить каждую поисковую строку, которая будет интерпретироваться как строка буквального , возможно с пробелами. Для этого требуется опция /C:.

C) - Вы предполагаете, ведущие пробелы не являются существенными в поисковой строке ("tokens=*" полосы ведущих мест)

D) - Вы предполагаете, не поисковые строки не начинаются точкой с запятой. (The 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 ... 

точка Е) может быть решена путем определения переменной и добавления управляющих последовательностей с помощью поиска и замены. Но для этого требуется отсроченное расширение, но замедленное расширение приведет к повреждению переменных 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 
) 
+0

Ваше предложение отлично работает. Спасибо. Кстати, есть только один JSON, с которым нужно иметь дело, и это одна строка. Кроме того, мне не нужно беспокоиться (например) о бат-ван против ванны. –

0

если я читаю ваш вопрос права (выход все линии check.txt, которые не в search.txt), это одна линия должна сделать:

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

Я хочу, чтобы проверить все элементы поиска .txt против огромного однострочного файла check.txt и выводить все строки search.txt, которые не находятся в файле check.txt. Поскольку check.txt - это одна строка, я не могу использовать метод, о котором вы думаете. –