I have many 7z archives nested in many subfolders, and want to extract all these archives into the folders in which they reside, then delete the original archives.

I have found how to do this, while extracting to the root directory.

while [ "`find . -type f -name '*.7z' | wc -l`" -gt 0 ]; do find -type f -name "*.7z" -exec 7za x -- '{}' \; -exec rm -- '{}' \;; done

However all archives are unpacked to the directory in which I carried out the command -- I want to extract said archives to their original locations preserving the original structure, but am not sure how to change it to do so.


Use -execdir instead of -exec;

find . -type f -name "*.7z" -execdir 7za x {} \; -exec rm -- {} \;

-execdir runs in the directory containing the file. From man find:

-execdir command {} +
      Like   -exec,   but  the  specified  command  is  run  from  the
      subdirectory containing the matched file, which is not  normally
      the  directory  in  which  you  started  find. 

Other comments:

Use -quit in the while check's find, so that find doesn't continue searching after a match was found (see https://unix.stackexchange.com/a/13880/70524):

while [ -n "$(find . -type f -name '*.7z' -print -quit)" ]
    find . -type f -name "*.7z" -execdir 7za x {} \; -exec rm -- {} \;
  • @Arronical that would be an excellent reaction on Unix & Linux, where one can't assume GNU find. – muru May 26 '15 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.