Если в Windows есть папка с несколькими файлами, скажем, папка c:/ с файлами, и внутри нее есть файлы с произвольным именем.

И у меня есть файл .txt с несколькими словами, скажем, c:/words/wordstofind.txt

Я хотел бы знать, есть ли способ, которым компьютер может войти, чтобы проверить, существует ли какое-либо из слов в wordstofind.txt внутри каждого из файлов в папке c:/ с файлами, и если хотя бы 1 существует, то дайте мне имена файлов из тех файлов в этой папке, которые содержат любое из слов в wordstofind.txt

Мне не нужно знать, какое слово он нашел, а также, если он найдет какое-либо слово, он может добавить имя файла этого файла для непосредственного результата и перейти к поиску следующего файла в папке (1 результат достаточен для перехода к файлу результата. ).

Файл результатов будет сохранен в C:/results/resultfilenames.txt

Когда я открываю файл resultfilenames.txt, он должен содержать только имена файлов, которые содержат любое из указанных слов, а не папку, если это возможно (что будет одинаковым для всех).

Спасибо

1 ответ1

0

Для нативного решения Windows, FINDSTR является возможным вариантом. Для вашего случая использования вы можете попробовать:

findstr /l /s /i /m /g:searchwords.txt /f:filestosearch.txt > results.txt 

Это говорит FINDSTR (соответственно):

  • Используйте поисковые слова как строковые литералы (а не регулярные выражения).

  • Рекурс подпапок.

  • Игнорировать чувствительность к регистру.

  • Печатайте только имена файлов (которые включают полный путь к каталогу).

Обратите внимание, однако, что FINDSTR имеет недокументированные ограничения и ошибки, которые могут не сделать его подходящим вариантом.

Для не нативного решения вас может заинтересовать порт утилиты grep , такой как GNUWin32 grep. Хотя реализации grep могут различаться в поддерживаемых ими опциях, GNUWin32 grep является портом GNU grep (хотя в настоящее время это v2.5.4, а не v3.0), который может читать условия поиска из файла. Для вашего случая использования вы можете попробовать:

grep -rilf C:\path\to\searchwords.txt C:\path\to\search > results.txt

Это говорит grep (соответственно):

  • Рекурс подпапок.

  • Игнорировать чувствительность к регистру.

  • Подавить нормальный вывод (только список файлов, включая полный путь).

  • Вытащить условия поиска из текстового файла.

И FINDSTR, и grep возвращают полные пути к файлу, поэтому вам, вероятно, потребуется выполнить дополнительную обработку для вывода любого из них. Имейте в виду, однако, что в отличие от FINDSTR, параметры grep обычно чувствительны к регистру. Например, -L не та же опция, что и -l (строчная буква L). Любые пути с пробелами требуют двойных кавычек ("") как обычно.

Если вы хотите искать только определенные файлы, вы можете указать их в командной строке индивидуально (например, doc1.txt doc2.txt doc3.txt) вместо каталога. При необходимости вы можете использовать полные пути (например, C:\path\to\doc1.txt).

Стоит также отметить, что причина, по которой я поместил файл «searchwords.txt» в отдельный каталог, заключается в том, что GNUWin32 grep в противном случае включит этот файл в "совпадающие" элементы.

Наконец, хотя в большинстве случаев GNUWin32 grep и не должен нарушать условия сделки, grep использует перевод строки в стиле Unix для вывода, а также сочетание \ и / для путей.

Обратите внимание, что в конце этого ответа есть некоторые дополнительные объяснения этих последних двух специфичных для GNUWin32 придирок grep ... так что вы можете также прочитать это. знак равно

Фиксация выхода с помощью sed

Поскольку вам нужны только имена файлов, мы можем использовать другую утилиту GNUWin32, которая называется sed, для их получения. Это порт GNU sed, «неинтерактивный текстовый редактор командной строки». Это означает, что эта программа может принимать текстовый ввод из командной строки, изменять его стандартным способом и выводить эти измененные данные.

В нашем случае с GNUWin32 grep мы можем использовать его для удаления всего перед каждым именем файла с помощью:

sed s/.\+[/+]//

Кроме того, мы можем трубу | вывод из grep в sed выглядит так:

grep -rilf C:\path\to\searchwords.txt C:\path\to\search | sed s/.\+[/+]// > results.txt

Это оставит только имя файла в "results.txt" и будет иметь дополнительное преимущество, заключающееся в устранении любых проблем с / и переводами строк в стиле Unix (все / удалены и, по крайней мере, при таком конвейере sed выдает нормальные разрывы строк Windows ).

Разбивка команды sed выглядит следующим образом:

  • s/ - начало команды замены.
  • .\+[/+] - это регулярное выражение (что мы хотим найти - в данном случае все, вплоть до последнего / в нашем выводе grep).
  • // это, соответственно, обязательный / разделитель между нашим элементом, который нужно найти, и нашей заменой, без пробела (пустая замена) и последний / обязательный для всех команд sed-замены.
  • sed может также использовать другие разделители, например + в случае конфликтов (скажем, с косой чертой в каталоге).
  • Отсутствие финала / приведет к ошибке «неопределенная команда».

Как небольшое предостережение, приведенная выше команда sed также удаляет информацию о подкаталогах, поэтому возвращаемые имена файлов могут не все находиться в одном (корневом) каталоге.

Вы можете прочитать больше о регулярных выражениях GNU sed здесь.


GNUWin32 grep Quirks

Newlines

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

В случае систем в стиле Unix (где возникла grep), это простой перевод строки, представленный как /n например

line 1 /n
line 2 /n

Windows похожа, но использует дополнительный возврат каретки, представленный как /r , перед переводом строки. Это приводит к объединению /r/n а не просто /n .

Хотя это обычно не проблема, некоторые программы Windows (такие как Блокнот Windows) ведут себя по-разному с однострочными каналами (/n). Одна общая проблема - заставить линии работать вместе, например

line1line2

Поскольку gnuwin32 Grep производит /n управляющие символы только и не /r/n этот вывод может привести к отправлены в файл (через «>» выше) , чтобы иметь читаемость или другие вопросы , в некоторых случаях. При необходимости это можно исправить, заменив управляющие символы /n на /r/n (возможно с помощью дополнительных сценариев) или просто используя программу, которая поддерживает чтение / замену этих символов (например, Notepad++).

Обратные разделители

Еще одна унаследованная особенность - это разница в разделителях, используемых для каталогов (путей) в Unix-стиле и системах Windows. В системах в стиле Unix разделителями являются косые черты, например

/path/to/some/file.txt

Windows, однако, использует обратную косую черту, например

C:\path\to\some\directory

GNUWin32 grep странным образом объединяет их, используя обычные обратные слеши для основного пути к каталогу и прямые косые черты для отображения результатов сопоставления файлов, например

C:\path\to\some\directory/match1.txt
C:\path\to\some\directory/subdirectory/match2.txt

Эту причуду можно преодолеть с помощью (опять же) дополнительных сценариев или простого поиска / замены в любом обычном текстовом редакторе.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .