I have a 7z archive file which, at the "root" level, contains a couple of files and then a directory, which in turn contains both files and folders, like this:
- file1.txt
- file2.txt
- my_dir - file3.txt - file4.txt - another_dir - file5.txt - file6.txtI would like to know if there is a single command that allows me to extract the content of my_dir inside a directory of my choice so that the end result is:
- target_dir - file3.txt - file4.txt - another_dir - file5.txt - file6.txtI have tried these commands:
7za x -y archive.7z -o/path/to/target_dir my_dir
7za x -y archive.7z -o/path/to/target_dir 'my_dir/*'but both created this directory structure:
- target_dir - my_dir - file3.txt - file4.txt - another_dir - file5.txt - file6.txt 2 2 Answers
Is there a single command that allows extracting my_dir to a specified directory?
Yes. Use the e option instead of x:
7za e -y archive.7z -o/path/to/target_dir my_dir(x is Extract with full paths)
e (Extract) command
Extracts files from an archive to the current directory or to the output directory. The output directory can be specified by -o (Set Output Directory) switch.
This command copies all extracted files to one directory. If you want extract files with full paths, you must use x (Extract with full paths) command.
Source e (Extract) command
But in fact the folder in the archive contains subfolders which I'd like to preserve
In this case you need to use the original command (with x), and then use move to move the contents of my_dir up a level.
Something like the following batch file (not tested):
@echo off
7za x -y archive.7z -o/path/to/target_dir my_dir
move /y my_dir\* /path/to/target_dir
rd /s my_dir
endlocalFrom the command line:
7za x -y archive.7z -o/path/to/target_dir my_dir && move /y my_dir\* /path/to/target_dir && rd /s my_dirBut I'm using Linux!
Then the commands to use are:
#!/bin/bash
7za x -y archive.7z -o/path/to/target_dir my_dir
mv -f my_dir/* /path/to/target_dir
rmdir my_dirOr:
7za x -y archive.7z -o/path/to/target_dir my_dir && mv -f my_dir/* /path/to/target_dir && rmdir my_dirWhich can probably be simplified by someone who knows bash better than I do.
Further Reading
- An A-Z Index of the Windows CMD command line | SS64.com
- Windows CMD Commands (categorized) - Windows CMD - SS64.com
- Move - Windows CMD - SS64.com
- RD - Remove Directory - Windows CMD - SS64.com
- Command Redirection, Pipes - Windows CMD - SS64.com
Managing multiple archives
Not sure if this was possible when the question was first asked, but there's a simpler solution that works with both x and e (x preserves folder structure, e flattens everything, so the one you're looking for is x):
7z x archive.7z -opath/to/dir
Both swtiches (here, x and -o) support wildcards:
7z x *.7z -o*
This would extract all .7z archives on the current directory to new subdirectories with the same name.
Source: -o (set Output directory) switch
Filtering to extract folders only
If the filetypes to be filtered are known, such as .txt in your example, 7z x archive.7z -opath/to/dir -x!*.txt will do the trick. Alternatively, you can filter out every name that includes a dot (.), so every file is excluded: 7z x archive.7z -opath/to/dir -x!*.*. Note that this will also filter out any folder including a dot (.) in its name