Recursive Directory Unzip

Discuss and share scripts and script files...
Post Reply
MediaManny
Posts: 4
Joined: 24 Jun 2021 10:57

Recursive Directory Unzip

Post by MediaManny »

I'm creating my first script and have made good progress until I reached the recursion where "Try Script" can be less helpful.

This is a recursive script, so the idea is that it must be a function that calls itself. Eventually it will do two things (a) recurse all folders/subfolders, then (b) enumerate and unzip any .ZIP/.RAR files that it finds in those folders.

Here's the current code:

Code: Select all

//Begin Script; Enumerate paths that have been selected in the XYplorer UI
foreach($dir, <get selecteditemspathnames |>, "|" ) {
    function folderList($dir);
}

//Function to parse folders, the call itself to parse subfolders.
//If there are .ZIP files, in addition to folders, those will be processed
function folderList($dir) {
   $folderList = listfolder($dir, "*", 2, "|");
   foreach($folder, $folderList, "|") {
      //for each folder, enumerate that by calling this same function
      function folderList($folder);
   }
   $fileList = listfolder($dir, "*.zip;*.rar;*.7z", 1, "|");
   foreach($file, $filelist, "|") {
      echo $file;
      //unzip goes here, once working.
   }
}
All of the code seems to work; however, the recursion doesn't seem to be working.

Any ideas what I might be doing wrong? Or, f there are similar examples that you can link, that might help me find the problem. Unfortunately I haven't been able to find any similar examples. I have found many topics on recursion; none of them that actually appeared to be true recursion that would work for my purposes.

Thank you in advance!

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Recursive Directory Unzip

Post by highend »

You don't need any recursion at all to do what you want...
But good to see that there are still people that try to do something on their own before they ask for help :tup:

Code: Select all

    $archives = quicksearch("*.7z;*.rar;*.zip", <get SelectedItemsPathNames |>);

    foreach($archive, $archives, <crlf>, "e") {
        status "Extracting " . gpc($archive, "file") . " ...", , "progress";
        zip_extract($archive, gpc($archive, "path") . "\" . gpc($archive, "base"));
    }
Don't forget to set these key/value pairs in the XYplorer.ini file (while XY is NOT running)
and adapt the paths, if... your are using portable versions (if you're using installed ones they shouldn't be necessary)

Code: Select all

ZipPathUnRAR=D:\Tools\WinRAR_x64\UnRAR.exe
ZipPath7zip=D:\Tools\7-Zip\7z.exe
One of my scripts helped you out? Please donate via Paypal

admin
Site Admin
Posts: 60357
Joined: 22 May 2004 16:48
Location: Win8.1 @100%, Win10 @100%
Contact:

Re: Recursive Directory Unzip

Post by admin »

FYI, your recursive script is okay, but you spelled $filelist instead of $fileList once. Variables are case-sensitive in XY scripting.

MediaManny
Posts: 4
Joined: 24 Jun 2021 10:57

Re: Recursive Directory Unzip

Post by MediaManny »

Wow! Thank you so much, @highend and @admin -

@admin -
About the type-o, I'm worthless without IDE's + interpreters (lol). I'll waste 10x more time debugging due to a variable-name type-o than real issues!

@highend -
Your solution worked perfectly cut-and-paste without changes, thank you!

There was one item I didn't understand; the "get SelectedItemsPathNames" passed a pipe ("|") but the ForEach split on <crlf>.

This worked fine; however, I was curious if it would work if I split on pipe. Because it did, I left that as pipe rather than <crlf>.

While XYplorer was not running, I also modified one of the two .INI parameters you mentioned:

Code: Select all

ZipPathUnRAR=
ZipPath7zip=C:\Program Files\7-Zip\7z.exe
(I use 7-Zip for my RAR's and from the config help-file it appears this is the proper method?)

I did run into a small issue with using the intrinsic zip_extract command:

Code: Select all

zip_extract($archive, gpc($archive, "path") . "\" . gpc($archive, "base"));
Works fine; with two issues (1) it's very slow; (2) I see the Windows standard dialog "copying" files rather than 7-Zip; (3) I do not see 7z.exe run in the task manager.

My assumption was that I had a type-o in the path to 7z.exe; I pasted into a CMD prompt and it ran file.

I also tested by quoting the path; however, XYplorer would remove quotes upon exiting; therefore, I felt certain that it does not require quotes.

If anyone has ideas on what I might be doing wrong, I'd love to know for academic/learning purposes.

For now I've worked around this and will post so that future searches can find this example code. I've added a bunch of comments to help anyone new to this:

Code: Select all

 //Indent all lines by 1+ spaces
 //Populate $ArchiveList with Search-Results (combine with "|" delimiter)
 $archiveList = quicksearch("*.7z;*.rar;*.zip", <get SelectedItemsPathNames |>);

 //Split FileList by "|"  --  Skip "e"mpty files
 foreach($archive, $archiveList, "|", "e") {
   //Set the Status Display Msg in XYplorer GUI
   status "Extracting " . gpc($archive, "file") . " ...", , "progress";
   //echo $archive;  //For debugging
   //Intrinsic XYplorer extraction:
     //zip_extract($archive, gpc($archive, "path") . "\" . gpc($archive, "base"));
   //Alt:  Run 7-zip to extract  --  Extract to Orig Path + Create Dir named w/filename (no extension)
     run """C:\Program Files\7-Zip\7z.exe"" x ""$archive"" -o""" . gpc($archive, "path") . "\" . gpc($archive, "base") . """ -aoa -y";
 }
 //Clear Status Display
 status "";
Thank you again; the extent of XY's features are just insane. Calling it the "Swiss Army Knife" of File Managers would be a massive understatement ;-)

Now on to writing a script to make a few dozen search/replaces which I had been doing previously with D.O. using regex; however, this will be much cleaner in XYplorer w/Script + Catalog!

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Recursive Directory Unzip

Post by highend »

There was one item I didn't understand; the "get SelectedItemsPathNames" passed a pipe ("|") but the ForEach split on <crlf>.
quicksearch expects multiple paths to search separated via ";" or "|" but it's output is (by default if you don't choose otherwise) separated by <crlf>
Works fine; with two issues (1) it's very slow; (2) I see the Windows standard dialog "copying" files rather than 7-Zip; (3) I do not see 7z.exe run in the task manager.
The inbuilt (in Windows) zip functionality isn't the fastest... and it's still used for .zip files even if e.g. ZipPath7zip is defined. If the script extracts a .rar or .7z and uses 7z.exe for it, look in the Details tab in the task manager and you'll see the 7z.exe process

@Don: It would be nice when XY finds 7zip or Winrar available it would use them automatically even for .zip files. As a tweak if necessary (although I don't know why anyone would want the inbuilt zip functionality of Windows to be used at all in such a case)...
One of my scripts helped you out? Please donate via Paypal

jupe
Posts: 2757
Joined: 20 Oct 2017 21:14
Location: Win10 22H2 120dpi

Re: Recursive Directory Unzip

Post by jupe »

highend wrote: 25 Jun 2021 07:36 It would be nice when XY finds 7zip or Winrar available it would use them automatically even for .zip files. As a tweak if necessary
This is already possible, just need to add "zip." to ZipExtWinRAR=, which is also used by 7zip.

highend
Posts: 13274
Joined: 06 Feb 2011 00:33

Re: Recursive Directory Unzip

Post by highend »

Thanks jupe!

This is additionally required: ZipExtractUse7zip=1
if ZipPathUnRAR is defined as well, otherwise WinRAR will extract them
One of my scripts helped you out? Please donate via Paypal

Post Reply