Home > Software engineering >  How to pack files into a ZIP file which have same name but different suffixes?
How to pack files into a ZIP file which have same name but different suffixes?

Time:09-25

Here is an example for one file:

  • C:\folder\video\my-holiday-video.mp4
  • C:\folder\image\my-holiday-screen.png
  • C:\folder\mix\my-holiday-HDphoto.jpg
  • C:\folder\cover\my-holiday-art.jpg

What I try to do is to make a ZIP archive of files which are in different folders, but have the same name, i.e. my-holiday for the example above, but a different suffix as -video or -screen or -HDphoto or -art and keep the same folder tree in each ZIP file.

The result should be my-holiday.zip which contains all the files in their folders.

I have success with this code on all the files have the same name:

@for %%I in ("%~dp0wheel\*") do @"%ProgramFiles%\7-Zip\7z.exe" a -bd -bso0 -mx0 -r -x!*.zip -y "%~dp0%%~nI.zip" "%~dp0%%~nI.*"

But it zips only when files have all the strict same file name.

Is there a way to make my batch ignore the suffixes -video, -screen, -HDphoto and -art in the name of each file in order to make them zip together?

Here are the requirements:

  1. The suffixes -video, -screen, -HDphoto and -art are always the same for all my files. So these are fixed in the file names.

  2. There should be in the file my-holiday.zip:

    • video\my-holiday-video.mp4
    • image\my-holiday-screen.png
    • mix\my-holiday-HDphoto.jpg
    • cover\my-holiday-art.jpg

    Each file is with its relative path in the ZIP archive. So when I decompress them, they'll be extracted in their directories, for example my-holiday-video.mp4 will decompress into folder video, my-holiday-HDphoto.jpg into folder mix, etc. like my actual code do it.

  3. The rule for common part of a files collection is that everything left to -video before file extension .mp4 should be used as common part of the file names to pack into the ZIP file.

  4. The folder video is the source for packing the files with common name into a ZIP file.

CodePudding user response:

The task could be done with following batch file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
cd /D "C:\folder" || exit /B
for %%I in ("video\*-video.*") do (
    set "VideoFileName=%%~nxI"
    setlocal EnableDelayedExpansion
    set "CommonName=!VideoFileName:-video%%~xI=!"
    "%ProgramFiles%\7-Zip\7z.exe" a -bd -bso0 -mx0 -y -- "!CommonName!.zip" "cover\!CommonName!-art.*" "image\!CommonName!-screen.*" "mix\!CommonName!-HDphoto.*" "video\!VideoFileName!"
    endlocal
)
endlocal

The batch file defines with the first two command lines the required execution environment which is:

  • command echo mode turned off
  • command extensions enabled
  • delayed expansion disabled

The next command changes the current directory to C:\folder. If that command fails because of the directory does not exist or a UNC path is used instead of a path starting with a drive letter and a colon, the batch file processing is exited without any further message than the error message output by command CD.

The FOR loop searches in subdirectory video for non-hidden files matching the wildcard pattern *-video.*. The file name with file extension of a found video file matching this wildcard pattern is assigned to the environment variable VideoFileName.

Next delayed expansion is enabled as required to make use of the file name assigned to the environment variable VideoFileName. Please read this answer for details on what happens in background on execution of setlocal EnableDelayedExpansion and later on execution of corresponding endlocal.

A case-insensitive string substitution using delayed expansion is used to remove from video file name -video left to the file extension and the file extension itself which can be .mp4, .mpg, .mpeg, etc. VideoFileName was defined with file extension in case of the file name itself contains anywhere the string -video which should not be removed by the string substitution. For example My Home-Video-video.mp4 assigned to VideoFileName results in My Home-Video getting assigned to the environment variable CommonName because of taking also the file extension into account on string substitution.

Next 7-Zip is executed with the command a and the switches as posted in question to create or add to a ZIP file in current directory with common name part of the files in the four directories and file extension .zip the video file name and the other image files from the other three directories with whatever file extension the images have in the other three directories.

Then endlocal is executed to restore the previous environment with delayed expansion disabled again.

The commands setlocal EnableDelayedExpansion and endlocal are used inside the FOR loop to be able to process correct also a files collection with a common name like Superman & Batman ( Robin!) containing an exclamation mark.

The video files in subdirectory video define which files to pack into a ZIP file. So all image files in the three image directories are ignored for which no video file exists in directory video.

Note: The batch file is not capable processing correct video file names which contain an exclamation mark in the file extension. I doubt that this limitation is ever a problem as I have never seen a video file extension with an exclamation mark.

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.

  • cd /?
  • echo /?
  • endlocal /?
  • exit /?
  • set /?
  • setlocal /?

See also single line with multiple commands using Windows batch file for an explanation of conditional operator ||.

  • Related