Запрос справки пакетного сценария: Как найти разрыв строки?

У меня есть несколько файлов RAR, содержащих JPG, и я пытаюсь получить имя первого файла каждого файла RAR.

Например, если я бегу 7z l -r abc.rarЯ хотел бы получить первый файл 01.jpg

path = xyz.rar
Type = zip
Physical Size = 15430338

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2003-03-06 13:32:44 ....A       330433       325405  01.jpg
2003-03-06 13:34:08 ....A       301098       291857  02.jpg
2003-03-06 13:34:14 ....A       257770       244619  03.jpg
2003-03-06 13:34:22 ....A       301220       292019  04.jpg
2003-03-06 13:34:30 ....A       326989       316380  05.jpg

Пока что с помощью следующего пакетного сценария я могу удалить метаданные команды 7z и получить список файлов в contents.txt файл.

set PATH=%PATH%;"C:\Program Files\7-Zip"

for %%f in ("*.*") do (
    echo "%%f" >> contents.txt
    echo.

    7z l -r "%%f" | FIND /V "ing " | FIND /V "Igor Pavlov" | FIND /V "--" | FIND /V "Path" | FIND /V "Type" | FIND /V "Solid" | FIND /V "Blocks" | FIND /V "Multivolume" | FIND /V "Volumes" | FIND /V "Date" | FIND /V "---" | FIND /V "Physical Size" | FINDSTR /R /E ".jpg" >> contents.txt

    echo.
)
PAUSE

Пример вывода:

"abc.rar" 
2003-03-26 01:18:50 ....A       331711       330648  01.jpg
2003-03-26 01:18:54 ....A       271173       270942  02.jpg

"xyz.rar" 
2003-07-08 22:40:56 ....A       445799       430058  p00.jpg
2003-07-08 22:40:40 ....A       181324       142554  p01.jpg
2003-07-08 22:40:42 ....A       384901       370140  p02.jpg

"efg.rar" 
2003-07-08 22:42:54 ....A       156436       115275  xy01abc.jpg
2003-07-08 22:42:58 ....A       456633       448240  xy02abc.jpg
2003-07-08 22:42:58 ....A       355114       339026  xy03abc.jpg
2003-07-08 22:42:58 ....A       355114       339026  xy04abc.jpg

Я думаю, что если я настрою свой сценарий, чтобы найти первый разрыв строки, за которым следует ".jpg" в выводе 7z, я могу получить имя первого файла в следующем формате:

"abc.rar" 
2003-03-26 01:18:50 ....A       331711       330648  01.jpg

"xyz.rar" 
2003-07-08 22:40:56 ....A       445799       430058  p00.jpg

"efg.rar" 
2003-07-08 22:42:54 ....A       156436       115275  xy01abc.jpg

Но я не знаю, как искать разрыв строки в команде FINDSTR. Я пытался найти для ".jpg\n" в FINDSTR:

7z l -r "%%f" | FIND /V "ing " | FIND /V "Igor Pavlov" | FIND /V "--" | FIND /V "Path" | FIND /V "Type" | FIND /V "Solid" | FIND /V "Blocks" | FIND /V "Multivolume" | FIND /V "Volumes" | FIND /V "Date" | FIND /V "---" | FIND /V "Physical Size" | FINDSTR /R /E ".jpg\n" >> contents.txt

Но это не сработало.

Может кто-нибудь мне помочь?

Мой желаемый вывод - убрать всю информацию о дате и размере файла из вывода имени файла и добавить ее после имени файла RAR, например:

"abc.rar" 01.jpg

"xyz.rar" p00.jpg

"efg.rar" xy01abc.jpg

Не существует фиксированного шаблона первого файла jpg. Некоторые начинаются с 00, некоторые с 01, некоторые с текстом и номером (пример x00y.jpg). Я пробовал различные методы для поиска имен файлов, которые начинаются с 00 или 01 с текстом и без текста (например, в моей команде я использовал FINDSTR /R /E "[a-z][0-1]*.jpg" искать имена файлов с текстом и номером, но есть некоторые файлы RAR без текста в именах файлов).

1 ответ

Выполнение в окне командной строки findstr /? выводит справку для этого списка команд и объяснения /E искать указанную строку в конце строк. Используя эту опцию намного проще, чем все остальное, найти строку в конце строки.


Одним из возможных пакетных решений для вашей задачи может быть:

@echo off
del contents.txt 2>nul
for %%A in ("*.*") do call :GetFirstFileName "%%~A"
exit /B

:GetFirstFileName
"%ProgramFiles%\7-Zip\7z.exe" l "%~1" | %SystemRoot%\System32\findstr.exe /E /I "/C:.jpg">"%TEMP%\FilesList.tmp"
for /F "usebackq eol=` tokens=5* delims= " %%B in ("%TEMP%\FilesList.tmp") do (
    echo "%~1" %%C>>contents.txt
    del "%TEMP%\FilesList.tmp"
    exit /B
)
del "%TEMP%\FilesList.tmp"
exit /B

Этот пакетный файл вызывает 7-Zip для каждого файла в текущем каталоге, чтобы вывести содержимое архива, отфильтрованного с помощью findstr, чтобы попасть во временный файл списка только строк, заканчивающихся на .jpg в любом случае.

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


Другим решением было бы использование FOR напрямую для обработки вывода списка 7-Zip.

@echo off
setlocal EnableDelayedExpansion
del contents.txt 2>nul
for %%A in ("*.*") do call :GetFirstFileName "%%~A"
endlocal
exit /B

:GetFirstFileName
set "NextLine=0"
"%ProgramFiles%\7-Zip\7z.exe" l "%~1">"%TEMP%\FilesList.tmp"
for /F "usebackq eol=` tokens=1,5* delims= " %%B in ("%TEMP%\FilesList.tmp") do (
    if "%%B" == "-------------------" (
        set "NextLine=1"
    ) else if "!NextLine!" == "1" (
        echo "%~1" %%D>>contents.txt
        del "%TEMP%\FilesList.tmp"
        exit /B
    )
)
del "%TEMP%\FilesList.tmp"
exit /B

Этот пакетный файл вызывает 7-Zip для каждого файла в текущем каталоге, чтобы вывести содержимое архива, перенаправленного во временный файл списка.

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

Число строк над списком не является постоянным, что является причиной, почему опция FOR skip= не может быть использован здесь.

Не имеет значения, какое расширение имеет первый файл в архивном файле для этого пакетного решения.


Еще одним решением является использование бесплатного UnRAR для получения первого имени каждого файла архива RAR.

@echo off
del contents.txt 2>nul
for %%A in ("*.rar") do call :GetFirstFileName "%%~A"
exit /B

:GetFirstFileName
"%ProgramFiles%\WinRAR\UnRAR.exe" lb "%~1">"%TEMP%\FilesList.tmp"
for /F "usebackq eol=: delims=" %%B in ("%TEMP%\FilesList.tmp") do (
    echo "%~1" %%B>>contents.txt
    del "%TEMP%\FilesList.tmp"
    exit /B
)
del "%TEMP%\FilesList.tmp"
exit /B

Преимущество состоит в том, что UnRAR поддерживает несколько опций для формата списка, включая пустой формат, используемый при использовании команды l с b прилагается. Это значительно упрощает получение первого имени файла.


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

  • call /?
  • del /?
  • echo /?
  • endlocal /?
  • exit /?
  • findstr /?
  • for /?
  • if /?
  • set /?
  • setlocal /?
  • "%ProgramFiles%\7-Zip\7z.exe" -?
  • "%ProgramFiles%\WinRAR\UnRAR.exe" /?
Другие вопросы по тегам