First, I suggest opening help file 7zip.chm
in program files directory of 7-Zip with a double click. Open on Contents tab the list item Command Line Version and next the list item Commands and click on l (List) to open the help page for listing archive file contents.
The batch file below uses 7-Zip with the command l
with the switches -i
(include) and -slt
(show technical information). The batch file expects to find the *.cue file in root of each *.7z archive file and therefore does not use the option to search for *.cue files in archive recursively.
Second, open a command prompt window in directory containing the about 600 *.7z archive files and run the command line:
"%ProgramFiles(x86)%\7-Zip\7z.exe" l -i!*.cue -slt "Crash Bandicot PSX 1995.7z"
7-Zip outputs the list of *.cue files inside archive Crash Bandicot PSX 1995.7z
with showing technical information. Now with knowing how the output of 7-Zip (of version 16.04 as used by me) looks like, the options used in batch file for second FOR loop can be understood better.
The batch file below searches only in current directory for *.7z files and renames all files containing a *.cue file if name does not already match.
Insert DIR option /S
(search also in subdirectories) after /B
(bare format) in case of the *.7z files are not all in current directory, but in current directory and its subdirectories.
Here is the comment batch file for this archive file renaming task:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Prepend folder path to 7z.exe temporarily to local copy of environment
rem variable PATH to be able to call 7z.exe without full path enclosed in
rem double quotes as this would make the FOR command line running 7z.exe
rem really very difficult.
set "PATH=%ProgramFiles(x86)%\7-Zip;%PATH%"
set "PauseOnWarning=0"
rem Search in current directory for *.7z files using command DIR and not FOR
rem directly and call for each found file the subroutine RenameArchiveFile
rem with file name enclosed in double quotes. It is important not using FOR
rem for searching for *.7z files as the found *.7z files are renamed while
rem executing the loop. A *.7z file could be easily processed more than once
rem on using command FOR directly. Better is in this case to use command DIR
rem which first search for all *.7z files (including hidden ones which FOR
rem would not do) and then outputs the names of all found files being
rem processed next by command FOR. So it does not matter that file names
rem change while FOR processes the list of file names output by DIR.
for /F "delims=" %%I in ('dir /A-D /B *.7z 2^>nul') do call :RenameArchiveFile "%%I"
rem Output an empty line and halt batch file execution if any warning
rem was output while processing the *.7z files in the subroutine.
if %PauseOnWarning% == 1 echo/ & pause
rem Restore previous command line environment and exit batch processing.
endlocal
goto :EOF
rem RenameArchiveFile is a subroutine called with name of the archive file
rem enclosed in double quotes. The file name can be with or without path.
rem 7-Zip is executed to output the list of *.cue files with showing
rem technical information for easier parsing the output lines. Any error
rem message output by 7-Zip is suppressed by redirecting them from STDERR
rem to device NUL. It is not expected that 7-Zip outputs an error at all.
rem The first 14 lines are always skipped by command FOR. The next lines
rem are split up into two substrings using space and equal sign as string
rem delimiters. The first substring is assigned to loop variable A and
rem everything after first substring and 1 to n spaces/equal signs is
rem assigned to loop variable B. There is hopefully no *.cue file which
rem begins unusually with an equal sign or a space character.
rem If the first substring (token) from current line assigned to loop
rem variable A is case-sensitive the word Path, it is expected that the
rem second substring (token) assigned to loop variable B is the name of
rem the *.cue file found in the current archive file. In this case the
rem file name is assigned to an environment variable and loop is exited
rem with a jump to label HaveFileName.
rem A warning message is output if no *.cue file could be found in archive.
:RenameArchiveFile
for /F "skip=14 tokens=1* delims== " %%A in ('7z.exe l -i!*.cue -slt %1 2^>nul') do (
if "%%A" == "Path" (
set "FileName=%%B"
goto :HaveFileName
)
)
echo Warning: Could not find a *.cue file in: %1
set "PauseOnWarning=1"
goto :EOF
rem A *.cue file was found in current archive. The file extension cue
rem at end is replaced by 7z for the new name of the archive file.
rem First it is checked if the current archive file has already the file
rem name of the *.cue file inside the archive in which case the subroutine
rem RenameArchiveFile is exited resulting in processing of batch file being
rem continued on main (first) FOR loop.
rem If there is no *.7z file in directory of current archive file with
rem the new name, the current archive file is renamed to new name and
rem subroutine RenameArchiveFile is exited without further processing.
rem But if a different archive file than current archive file has already
rem the new archive file name, the subroutine outputs a 3 lines warning
rem and exits without renaming the current archive file. The user has to
rem handle this file name collision.
:HaveFileName
set "FileName=%FileName:~0,-3%7z"
if "%FileName%" == "%~nx1" goto :EOF
if not exist "%~dp1%FileName%" ren %1 "%FileName%" & goto :EOF
echo Warning: Could not rename %1
echo to "%FileName%"
echo because a file with that name already exists.
set "PauseOnWarning=1"
goto :EOF
It might be a good idea to first insert command echo
left of rename command ren
near and of the batch file and insert pause
in a line between endlocal
and goto :EOF
to test how the *.7z files would be renamed without really doing it.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
7z
... 7-Zip is not using standard Windows syntax for options, but outputs a brief help on running without any parameter or with just -h
as parameter.
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
rem /?
ren /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul
used in this batch file twice with escaping the redirection operator >
with caret character ^
to get >
interpreted as literal character on parsing FOR command line by Windows command interpreter and later on execution of DIR command line by FOR as redirection operator.
And see Single line with multiple commands using Windows batch file for understanding what an ampersand &
means in command lines if not being present within a double quoted string.