How to recursively extract all .tar and .tgz file zipped in a .tgz file using 7zip command line version

0

1

I'm using 7zip cmd line version in my app (written in Python on Win 7 box) to extract .tgz files. Although I'm using the -r switch, the .tar and .tgz subdirectories are not extracted. Can someone tell me if I'm overlooking something or give some direction ... thanks! Below is a variant of the command that I've tried thusfar:

C:> 7za e c:\Extracted\name.tgz -oc:\PathFolder *.tar -r

suffa

Posted 2012-02-19T16:41:09.217

Reputation: 595

To clarfiy. Do you have archives with other archives in them, or do you have a set of folders that all have .tar and .tgz files in them? – soandos – 2012-02-19T16:44:13.723

@soandos "archives with other archives in them ..." – suffa – 2012-02-19T16:51:54.530

Answers

3

Here is code that should do what you want (note: It preserves all of the directory structures. If you do not want that, change the x to an e. Run this in powershell)

$cont=true  
cd c:\Extracted  
$TarFilesToExtract = get-childItem *.tar -Recurse  
$TgzFilesToExtract = get-childItem *.tgz -Recurse  
foreach($file in $TarfilesToExtract)  
{   
    7z x $file -oC:\Pathfolder    
}  
foreach($file in $TgzFilesToExtract)    
{  
    7z x $file -oC:\Pathfolder
}  
cd c:\Pathfolder  
while($cont -eq "true")  
{  
    $TarFilesToExtract = get-childItem *.tar -Recurse  
    $TgzFilesToExtract = get-childItem *.tgz -Recurse  
    if($TarFilesToExtract.Length -eq 0 -and $TgzFilesToExtract -eq 0)  
    {  
        $cont = "False"  
    }  
    else  
    {  
        foreach($file in $TarfilesToExtract)  
        {  
            7z x $file  
        }  
        foreach($file in $TgzFilesToExtract)  
        {  
            7z x $file  
        }  
    }  
}  

A shorter simpler version:

$cont=true
cd c:\Extracted
$files = get-childItem -include *.tar,*.tgz -Recurse
foreach($file in $TarfilesToExtract)
{
    7z x $file -oC:\Pathfolder
}
cd c:\Pathfolder  
while($cont -eq "true")
{
    $files = get-childItem -include *.tar,*.tgz -Recurse
    if($files.Length -eq 0)
    {
        $cont = "False"
    }
    else  
    {
        foreach($file in $files)
        {
            7z x $file 
        }
    }
}

soandos

Posted 2012-02-19T16:41:09.217

Reputation: 22 744

This seems like it would work perfectly, but I'm not so sure that I can build powershell in my wxPython app like I can 7zip (open source), that it can be installed (at same time w/ app) on any number of PCs running win xp or higher in my work environment? – suffa – 2012-02-19T18:19:39.530

@suffa, you could save it as a .ps1 file, and then run it through the command line (same way you are running 7zip) as powershell script1.ps1 – soandos – 2012-02-19T19:52:03.240

one question, what would be the correct syntax to only extract .log and .txt with 7zip command line? This works for logs: 7za.exe e c:\Extracted -oc:\Extracted *.log -r (I've tried *.log && *.txt ... but didn't work). – suffa – 2012-02-19T20:13:28.423

@suffa, so I am not really that good with powershell, so I would just do the same thing twice, once for .log and once for .txt – soandos – 2012-02-19T20:16:15.243

0

These are my 5 cent to this issue: I created following script to unpack all .7z and all .zip files recursively in my folder structure.

Might not be required by you - so you can just drop those lines if you like: - Because I plan to remove all .7z and .zip files after extraction, I created a cleanup.ps1 file (I didn't deleted the archives immediately for safety reasons). - In case of any extraction errors, I've put the extraction commands into the file ExecUnpack.ps1 to be able to extract single archive again

del "Cleanup.ps1"; 
del "ExecUnpack.ps1"; 
del "ExecUnpack.cmd"; 
get-childitem . -recurse -include @("*.7z","*.zip") | foreach { 
    """C:\Program Files\7-Zip\7z.exe"" x ""$($_.FullName)"" -y -o""$($_.FullName.Replace(" .7z", "\").Replace(".7z", "\").Replace(" .zip", "\").Replace(".zip", "\"))""" | Out-File -Append "ExecUnpack.ps1"
    """C:\Program Files\7-Zip\7z.exe"" x ""$($_.FullName)"" -y -o""$($_.FullName.Replace(" .7z", "\").Replace(".7z", "\").Replace(" .zip", "\").Replace(".zip", "\"))""" | Out-File -Append "ExecUnpack.cmd"
    $proc=[System.Diagnostics.Process]::Start("C:\Program Files\7-Zip\7z.exe", "x ""$($_.FullName)"" -y -o""$($_.FullName.Replace(" .7z", "\").Replace(".7z", "\").Replace(" .zip", "\").Replace(".zip", "\"))"""); 
    $proc.WaitForExit(); 
    echo "ExitCode=$($proc.ExitCode.ToString()) - $($_.FullName)"; 
    "#ExitCode=$($proc.ExitCode.ToString()) - $($_.FullName)" | Out-File -Append "Cleanup.ps1"; 
    "del ""$($_.FullName)""" | Out-File -Append "Cleanup.ps1"; 
}

Where this is the main part:

get-childitem . -recurse -include @("*.7z","*.zip") | foreach { 
    $proc=[System.Diagnostics.Process]::Start("C:\Program Files\7-Zip\7z.exe", "x ""$($_.FullName)"" -y -o""$($_.FullName.Replace(" .7z", "\").Replace(".7z", "\").Replace(" .zip", "\").Replace(".zip", "\"))"""); 
    $proc.WaitForExit(); 
    echo "ExitCode=$($proc.ExitCode.ToString()) - $($_.FullName)"; 
}

Jochen

Posted 2012-02-19T16:41:09.217

Reputation: 1

0

This worked well for me:

FOR /R "C:\whatever" %I IN (*.gz) DO .7z x "%I" -aou -o"%~dpI"

C:\whatever being the path to look in, *.tgz being the file types to extract and .7z being the location of 7zip (on the PATH in this case).

I also wanted to remove all the compressed files afterwards:

FOR /R "C:\whatever" %I IN (*.gz) DO del "%I"

As mentioned in the thread linked, it would be a good idea to test the command first with an @ECHO:

FOR /R "C:\whatever" %I IN (*.gz) DO @ECHO.7z x "%I" -aou -o"%~dpI"

hajamie

Posted 2012-02-19T16:41:09.217

Reputation: 178