Extract folder content from 7z archive to specific folder

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.txt

I 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.txt

I 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

Solution 1:

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
endlocal

From 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_dir

But 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_dir

Or:

7za x -y archive.7z -o/path/to/target_dir my_dir && mv -f my_dir/* /path/to/target_dir && rmdir my_dir

Which 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