Unzipping a .tar.gz or .tgz double zipped file
- Nov. 11, 2024
Introduction
When we download a backup file of a TM1 V12 (IBM Planning Analytics Engine or PAE) database, we receive a zipfile format. The extension is .tgz, and a similar extension is .tar.gz. Installation files from IBM are often compressed to such zipfiles. When we want to unzip the file contents, we need to unzip twice:
- First, unzip the file into a .tar zipped file format
- Second, unzip that .tar file to files and folders
You could use 7zip to do the work but it means 2 zip actions. Not the end of the world but still useful to automate. Since the manual approach also means that you will have nested files and folders, the tar subfolder is still stuck in there, I wanted to have code as I do not want that setup. The AutoHotKey code below will investigate all open File Explorer windows and list the double zipped zipfiles it can find in the selected/visible paths. Then the user can select a file and the code will turn the zipfile into files and folders. That new folder starts at the same location as the zipped folder. Change the shortcut key if wanted.
Pictures:
Automation with AutoHotKey
^q:: ; Press Ctrl+Q to run the script { cPath_7zip := A_ProgramFiles "\7-Zip\7z.exe" tgzFiles := [] ; Array to store .tgz and .tar.gz files ; Loop over all open File Explorer windows uniquePaths := {} for window in ComObjCreate("Shell.Application").Windows { if (window.Name = "File Explorer" || window.Name = "Windows Explorer") { folderPath := window.document.folder.Self.Path ; Search for .tgz and .tar.gz files in the current folder Loop, Files, %folderPath%\*.tgz if (!uniquePaths.HasKey(A_LoopFileFullPath)) { uniquePaths[A_LoopFileFullPath] := true tgzFiles.Push(A_LoopFileFullPath) } Loop, Files, %folderPath%\*.tar.gz if (!uniquePaths.HasKey(A_LoopFileFullPath)) { uniquePaths[A_LoopFileFullPath] := true tgzFiles.Push(A_LoopFileFullPath) } } } ; If no .tgz or .tar.gz files are found, show a message and exit if (tgzFiles.MaxIndex() = 0) { MsgBox, 48, No Compressed Files, No .tgz or .tar.gz files were found in the open File Explorer windows. return } ; Create a GUI with a ListView to display and select from the list of compressed files Gui, New, +AlwaysOnTop +LabelMyGui Gui, Add, Text,, Select a compressed file to extract: Gui, Add, ListView, vSelectedFilePath w500 h300 gOnListViewDoubleClick_DoubleUnZip, File Path for index, file in tgzFiles LV_Add("", file) LV_ModifyCol(1, "AutoHdr") ; Automatically adjust column width to fit content Gui, Add, Button, gExtractFile, Double extract Gui, Show,, Select Compressed File return } ExtractFile: ; Retrieve the selected file path from the ListView LV_GetText(selectedFilePath, LV_GetNext()) ; Get text of selected item if (!selectedFilePath) { MsgBox, 48, No Selection, Please select a file before clicking Extract. return } Gui, Destroy ; Define the target extraction folder next to the selected file fileNameNoExt := SubStr(selectedFilePath, 1, InStr(selectedFilePath, ".", 0, 0) - 1) extractionFolder := fileNameNoExt . "_extracted" ; Create the extraction folder if it doesn't exist FileCreateDir, %extractionFolder% ; Step 1: Extract the .tgz or .tar.gz file to get the .tar file RunWait, %ComSpec% /c ""%cPath_7zip%" e "%selectedFilePath%" -o"%extractionFolder%"", , Hide ; Locate the .tar file inside the extraction folder Loop, Files, %extractionFolder%\*.tar { tarFile := A_LoopFileFullPath break } ; Step 2: Extract the .tar file directly into the extraction folder without subfolders if (tarFile) { RunWait, %ComSpec% /c ""%cPath_7zip%" x "%tarFile%" -o"%extractionFolder%" -aos", , Hide FileDelete, %tarFile% ; Clean up the .tar file MsgBox, 64, Extraction Complete, Files have been successfully extracted to:`n%extractionFolder%. } else { MsgBox, 48, Error, No .tar file found after extracting %selectedFilePath%. } return OnListViewDoubleClick_DoubleUnZip: ; Handle double-clicking a list item to select it GoSub, ExtractFile return MyGuiClose_DoubleUnZip: Gui, Destroy return
Files that are visible in more than 1 File Explorer window will be shown only once. That will speed up the choice of path in the ListView.