Хорошо, если я вас правильно понимаю, вы хотите:
- Переместить файл в определенный каталог
- В зависимости от того, присутствует ли определенное слово в файле или нет
- Это должно быть сделано для всех файлов в каталоге
Если я правильно понял, то на самом деле это очень просто.
Краткий ответ:
for %%f in (*) do (
findstr "foo" "%%f" > NUL 2>&1
if not errorlevel 1 copy "%%f" "some_directory"
)
Более подробное объяснение:
Прежде всего, перебор набора файлов (да, «все файлы» также набор файлов) можно легко выполнить с помощью команды for
:
for %%f in (*) do ...
Затем вы хотите узнать, появляется ли в файле конкретное слово (давайте представим, что оно "foo"
) или нет. Это можно проверить с помощью команды findstr
:
findstr "foo" "%%f"
Теперь по умолчанию будет выводиться каждая строка, где "foo"
находится на экране. И, возможно, даже сообщения об ошибках, поэтому мы перенаправляем их в небытие:
> NUL 2>&1
findstr
возвращает конкретный числовой код в зависимости от того, была найдена данная строка или нет. В то время как вы обычно не можете видеть это, мы все еще можем проверить это. Этот конкретный код называется уровень ошибки , это предвещает времена Ye Olde DOS или, возможно, даже CP / M. В любом случае, этот уровень ошибки либо 0
, либо 1
. Если это 0, это означает, что текст был найден, когда он 1
, то текст либо не был найден, либо произошла другая ошибка.
Существует специальный синтаксис для проверки уровня ошибки, который имеет небольшую причуду: он проверяет, является ли уровень ошибки по крайней мере определенным числом. Поэтому для тестирования 0
нам нужно инвертировать его, но это не имеет большого значения:
if not errorlevel 1 copy "%%f" "some_directory"
Это перемещает файл в some_directory
, но только если уровень ошибки был , а не как минимум 1 , другими словами: ровно 0. Что означает, что текст, который мы искали в файле, был найден .
Собрав все это вместе, теперь это выглядит следующим образом:
for %%f in (*) do (
findstr "foo" "%%f" > NUL 2>&1
if not errorlevel 1 copy "%%f" "some_directory"
)
Это было не слишком сложно, не так ли?
P.S .: Мы можем немного сократить это, поскольку язык пакетных файлов имеет специальный синтаксис для выполнения команды только , когда другая команда завершается успешно:
for %%f in (*) do (findstr "foo" "%%f" >NUL 2>&1 && copy "%%f" "some_directory")
Теперь мы собрали его в одну строку. Но так как copy
также выводит текст, мы можем переместить перенаправление в конец строки, чтобы поймать как вывод findstr
, так и вывод copy
:
for %%f in (*) do (findstr "foo" "%%f" && copy "%%f" "some_directory") >NUL 2>&1
И так как это одна строка, нам больше не нужен командный файл (ну, строго говоря, нам это и раньше не нужно), и мы можем сбросить двойной %
, чтобы запустить его непосредственно из командной строки. :
for %f in (*) do @(findstr "foo" "%f" && copy "%f" "some_directory") >NUL 2>&1
Я включил @
перед открывающей скобкой, чтобы подавить вывод запущенных команд, иначе ваш экран быстро заполнится запущенными командами. В пакетном файле вы обычно просто включаете @echo off
в первой строке.