How can I extract multiple 7zip archives to folders with the same names in Linux?

9,013

Solution 1

You're trying to create a directory with the same name as the file. That cannot work: There can't be two directory entries with the same name.

One way to fix this is to use basename to strip the .7z extension from the files and create the directories without the .7z suffix.

Like:

for archive in *.7z; do 7z x -o"`basename \"$archive\" .7z`" "$archive"; done

Solution 2

To extract multiple *.7z files in the same directory with a single command, this will extract them all to separate directories named the same as the 7z archives without the .7z.

7za x -o* -y *.7z

Solution 3

for file in *.7z; do
    directory=${file/%.7z/}
    if mkdir ${directory}; then
        ( cd ${directory}; 7z x ../${file} )
    else
        echo "Unable to create directory ${directory} for archive ${file}" 1>&2
    fi
done

The way this works is first iterating through all the *.7z files using the file variable. Once it grabs a filename, it uses bash string manipulation to strip the .7z off the end, and make a new variable, directory, out of that.

It will then try to create the directory, and, if it can, it will open up a subshell, go into that directory, and extract the 7zip archive.

If it was not able to create that directory, a message is sent to standard error.

I use a subshell so as to not have to worry about losing track of where I am with changes to the working directory.

The most abstruse part of this is this line:

directory=${file/%.7z/}

This is the aforementioned bash string manipulation, which will look for .7z at the end of a string, and if present, replace it with nothing. If I wanted to replace it with, say, .zip, I could use ${file/%.7z/.zip}.

Share:
9,013

Related videos on Youtube

Admin
Author by

Admin

Updated on September 18, 2022

Comments

  • Admin
    Admin over 1 year

    I have about 300 7zip archives, each with several files in them, and no directory structure inside.

    I need to extract all these archives to folders that match the respective archive.

    Example:

    foo.7z
    bar.7z

    Extract contents of foo.7z to /foo/
    Extract contents of bar.7z to /bar/


    I tried this script:

    find . -name "*.7z" -type f| xargs -I {} 7z x -o{} {}

    But it resulted in:

    can not open output file ./foo.7z/file.bin
    Skipping    file.bin
    

    What am I doing wrong? I'm using Ubuntu Linux.

    • Admin
      Admin almost 7 years
      @platinums Pretty hard to use context menus on a non-graphical operating system.
  • Admin
    Admin over 8 years
    When I try that I get "there is no such archive".
  • Vojtech
    Vojtech over 8 years
    Did you have any spaces in the archive names? I have fixed the command in the answer to properly handle filenames that contain whitespace.
  • fixer1234
    fixer1234 over 8 years
    Can you expand your answer to explain what this code does, how to run it, and how it addresses the problem? Cautious readers are wary of unexplained code, and it's discouraged, because it doesn't teach the solution. Thanks.
  • Admin
    Admin over 8 years
    Ah, yes that was it. Thanks! Worked beautifully.
  • DopeGhoti
    DopeGhoti over 8 years
    Thanks for the feedback, @fixer1234, I have expanded upon my answer as you have requested.
  • Matthew K.
    Matthew K. over 4 years