Ищите имя файла из набора файлов (в CMD) - PullRequest
0 голосов
/ 02 октября 2019

Я хотел бы найти имя видеофайла в папке (в ней ~ 1000 файлов) с помощью командной строки Windows. Но ... есть проблема, я не помню имя видеофайла, у меня есть некоторые подсказки: видео было создано между 2019/02/01 до 2019/05/31 (формат: год / месяц / день), и час был между 09: 00: 00 до 13: 00: 00 (формат: час / минута / секунда).

Формат имени этого видеофайла: VID_YEARMONTHDAY_HOURMINUTESECOND.3gp , пример: VID_20190226_155112.3gp. Иногда имя видеофайла может иметь следующий формат: VID_YEARMONTHDAY_HOURMINUTESECOND WORDS.3gp , пример: VID_20190226_155112 EJEMPLO1.3gp

Я прочитал для команды из Документов Microsoft, и я создал ее:

for %A in (VID_201902* VID_201903* VID_201904* VID_201905*) do (for %B in (090000,1,130000) do (if %A:~0,19%==%A:~0,13%%B% echo %A%))

Не знаю, почему это не работает. Я объясню код: я получаю набор файлов в период с февраля по май, вложенный для идет от 090000 до 130000 (он представляет час), затем я сравниваю фактическое имя файла% A И имя файла% A с часом% B, потому чтокак я уже сказал, я хочу часов с 09:00:00 до 13:00:00. Наконец, если мое условие выполнено, я показываю имя видеофайла (% A).

Я знаю, что код не эффективен. Я спрашиваю: Почему код не работает?

1 Ответ

0 голосов
/ 04 октября 2019

Чтобы найти нужные видеофайлы, я бы использовал совершенно другой подход:

dir /B /A:-D "VID_*.3gp" | findstr /I /R /C:"^VID_20190[2-5][0-3][0-9]_09[0-5][0-9][0-5][0-9]" /C:"^VID_20190[2-5][0-3][0-9]_1[0-2][0-5][0-9][0-5][0-9]" /C:"^VID_20190[2-5][0-3][0-9]_130000"

Команда dir возвращает все файлы (/A:-D), имена которых начинаются сVID_ и заканчивается .3gp в виде пустого списка (/B) имен файлов, поэтому дополнительная информация не выводится. Этот список передан по каналу (|) в команду findstr , которая содержит три нечувствительных к регистру (/I) поисковых выражения (например, регулярные выражения /R), хотя findstr на самом деле не поддерживает истинные регулярные выражения, а лишь небольшую их выдержку), все из которых охватывают начало (^) имени файла (VID_), указанный диапазон дат (февраль. по май 2019 г.), _ и:

  • для охвата диапазона времени с 09:00:00 до 09:59:59: ^VID_20190[2-5][0-3][0-9]_09[0-5][0-9][0-5][0-9];
  • для охвата диапазона времени 10: От 00:00 до 12:59:59: ^VID_20190[2-5][0-3][0-9]_1[0-2][0-5][0-9][0-5][0-9];
  • для покрытия времени 13:00:00: ^VID_20190[2-5][0-3][0-9]_130000;

Относительно вашего кода: вы путаете for мета-переменные с обычными переменными среды ;первые выглядят как %A, %B и не поддерживают расширение подстроки (например, ~0,19);последние выглядят как %A%, %VAR%, могут быть определены как set и поддерживают что-то вроде %VAR:~0,19%. И, кстати, второй цикл должен быть for /L.

Сначала я бы немного расширил шаблоны имен файлов и использовал бы что-то вроде VID_201902??_*.3gp вместо VID_201902*, ноэто, конечно, зависит от того, какие имена файлов могут на самом деле встречаться.

Я также уменьшил бы строковую часть для сравнения на if, потому что первые 13 символов левого и правого выражениявсегда равны, поэтому их можно удалить, чтобы получить if "%VAR:~14,6%"=="%B" (позвольте мне порекомендовать использовать цитату для сравнения строк).

Другая проблема заключается в значении 090000 в for /L %B in (090000,1,130000) do, который будет рассматриваться как восьмеричное, а не как десятичное значение из-за ведущего 0 (см. set). Вместо этого вы могли бы указать 90000 и добавить начальный ноль к %B позже, тогда, когда это необходимо.

Поскольку цикл for /L должен повторяться 40001 раз для каждого файла, ваш код будет медленным. В качестве лучшей альтернативы вы можете сделать for /L %B in (9,1,13) do и просто сравнить значение часа, если только оно не равно 13, где в соответствии с вашими требованиями приемлемо только 130000.


Вы приближаетеськ рабочему варианту в вашем комментарии , но в нем отсутствует задержка расширения переменной , которая требуется, когда переменная записывается и читается в той же строке или (в скобках) блокаcode.

В любом случае, для объединения всего вышеперечисленного фиксированный код будет выглядеть примерно так, учитывая, что командная строка была запущена cmd /V:ON ранее для включения отложенного расширения:

for %A in ("VID_201902??_*.3gp" "VID_201903??_*.3gp" "VID_201904??_*.3gp" "VID_201905??_*.3gp") do @(set "STR=%~A" & for /L %B in (9,1,13) do @(set "NUM=%B" & (if !NUM! lss 10 set "NUM=0!NUM!") & if !NUM! lss 13 (if "!STR:~13,2!"=="!NUM!" echo/!STR!) else if "!STR:~13,6!"=="130000" echo/!STR!))

Тот же код будет выглядеть в пакетном сценарии следующим образом:

@echo off
setlocal EnableDelayedExpansion
for %%A in ("VID_201902??_*.3gp" "VID_201903??_*.3gp" "VID_201904??_*.3gp" "VID_201905??_*.3gp") do (
    set "STR=%%~A"
    for /L %%B in (9,1,13) do (
        set "NUM=%%B"
        if !NUM! lss 10 set "NUM=0!NUM!"
        if !NUM! lss 13 (if "!STR:~13,2!"=="!NUM!" echo/!STR!) else if "!STR:~13,6!"=="130000" echo/!STR!
    )
)
endlocal
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...