none
Batch file extracting all files from nested archives RRS feed

  • General discussion

  • I have managed to leverage a powerful forfiles command line utility with the mighty 7z compression program.

    Below is a simple batch file extracting all files from nested archives hidden at any depth inside other archives and/or folders. After the extraction each archive file turns into a folder having the archive file name. If, for example, there was an "outer.rar" archive file containing nothing but an "inner.zip" archive with only "afile.txt" inside, "outer.rar" becomes "...\outer.rar\inner.zip\afile.txt" file system path.

    @echo off
    rem extract_nested_archives.bat
    move %1 "%TMP%"\%2
    md %2
    7z x -o%1 -y %TMP%\%2
    del "%TMP%"\%2
    for %%a in (zip rar jar z bz2 gz gzip tgz tar lha iso wim cab rpm deb) do forfiles /P %1 /S /M *.%%a /C "cmd /c if @isdir==FALSE extract_nested_archives.bat @path @file"

    ARCHIVES ARE DELETED DURING THE EXTRACTION! Make a copy before running the script!

    "7z.exe" and "extract_nested_archives.bat" should be in folders available via the %PATH% environment variable.

    The first parameter of extract_nested_archives.bat is the full path name of the archive or folder that should be fully expanded; the second parameter is just the archive or folder name without the path. So you should run "c:\temp\extract_nested_archives.bat c:\temp\outer.rar outer.rar" from the command line to completely expand "outer.rar". "c:\temp" must be the current folder.


    Best regards, 0x000000AF

    Sunday, December 15, 2013 1:59 PM

All replies

  • Incredibly useful!  Thank you so much.  I did make a couple of small changes to make the script a little easier to use from the end-user perspective.

    First - I don't like making the user input the redundant second parameter, so I added this snippet which extracts it from the first parameter.  The first line of the snippet enables delayed expansion so that special characters in our file name don't break anything.  The second line pulls the parameter into a variable, and the 3rd line uses delayed expansion on that new variable.  Before implementing delayed expansion I had problems with file paths which included parentheses.

    SetLocal EnableDelayedExpansion Set SOURCE=%1 For %%Z in (!source!) do ( set FILENAME=%%~nxZ )
    set FILENAME=%FILENAME:"=%

    Anyway once that was done, I just used %FILENAME% everywhere in the script instead of %2 (making sure to correct quotes as needed)

    This way, to run my script all you need to run is:

    C:\temp\extract_nested_archives.bat C:\temp\Archive.zip

    Second - I didn't want to modify the Windows environment variable.  So I replaced 7z with "%PROGRAMFILES%\7-zip\7z.exe"

    I also replaced extract_nested_archives.bat with "%~f0" (which represents the full path+filename of the current script).

    Here is my full script now.  Tested on Windows 8 with the 64-bit version of 7-zip installed:

    @echo off
    Setlocal EnableDelayedExpansion
    Set source=%1
    For %%Z in (!source!) do (
    	set FILENAME=%%~nxZ
    )
    set FILENAME=%FILENAME:"=%
    move /Y %1 "%TMP%\%FILENAME%"
    md "%FILENAME%"
    "%PROGRAMFILES%\7-zip\7z.exe" x -o%1 -y "%TMP%\%FILENAME%"
    DEL "%TMP%\%FILENAME%"
    for %%a in (zip rar jar z bz2 gz gzip tgz tar lha iso wim cab rpm deb) do (
    	forfiles /P %1 /S /M *.%%a /C "cmd /c if @isdir==FALSE "%~f0" @path @file"
    )



    • Edited by Fëanor Wednesday, May 14, 2014 9:28 PM
    Wednesday, May 14, 2014 9:28 PM
  • Thank you, Fëanor! Your modifications are nice. Do you know that you can add other file extensions to the list? For example, I excluded chm because of terribly slow processing.

    Best regards, 0x000000AF

    Saturday, August 9, 2014 2:03 PM
  • A comment on this excellent and useful batch file: make sure you run it from the parent directory if you want to process nested archives below a pre-existing folder structure (i.e. in your file system). That is, do not use the command:

    C:\foo\bar> extract_nested_archives .    <-- do not use 'dot' for current directory

    Instead, do this:

    C:\foo> extract_nested_archives bar

    Thanks to the authors. It is a real time saver for me.

    Glenn



    Wednesday, September 10, 2014 7:33 PM
  • Thank you so much for this amazing script!  I'm trying to figure out how to exclude certain files from being processed.  Either by the script or by 7zip but cannot get it to work.  Basically I'd like to exclude a couple .tgz files from being extracted but to include all other .tgz files as normal.  

    For example.  I've tried the -xr!"*_filename.tgz" but it stops at that point.  Is there another way I can do this?
    Thursday, September 11, 2014 12:41 AM
  • Within the script try to call 7z with the -x (Exclude filenames) switch. I have no 7z installation at hand, so it's only a guess.

    Best regards, 0x000000AF


    • Edited by 0x000000AF Saturday, September 27, 2014 10:50 AM
    Saturday, September 27, 2014 10:45 AM
  • Nice script, I added a shortcut to this to my send to menu so that I can just right click -> Explode :-)

    Monday, October 26, 2015 11:38 AM