0

I have a group of folders that all have zip files in them that may contain 1 or 2 files in them each in a new folder. (see diagram below)

I want to point the script at the top level directory and have it to go through each sub directory, extract the contents of the zip, move the contents of that sub directory up one level (deleting the original zipped file optional).

--before--
Photos
-2018
--jan.zip
[--jan1     ]--\
[---jan1.pdf]---}-contents of Zipped file
[---jan1.JPG]--/
--feb.zip
[--feb1     ]--\
[---feb1.pdf]---}-contents of Zipped file
[---feb1.JPG]--/
...

--after--
Photos
-2018
--jan1.pdf
--jan1.JPG
--feb1.pdf
--feb1.JPG
  • 3
    What have your tried? – Peschke Jan 17 at 4:29
  • I may attempt a solution in python but I don’t do bash scripting. – Tommiie Jan 17 at 6:20
1

Before executing anything of the following, please do a (recursive) copy of your top level directory—just to be safe.

Than you can achieve what you want like so:

Make the top level directory (photos) your current working directory. Then extract all the zip files:

find . -iname "*.zip" -execdir unzip {} \;

Now move the contents of the extracted directories one level up:

find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;

This will not touch the zip files nor the extracted directories themselves, which become empty in this step. So you can delete them now:

find . -mindepth 2 -maxdepth 2 -type d -delete

Before you delete the zip files, double check that everything is okay. Then you can do the deletion with

find . -iname "*.zip" -delete

In principle you can combine these commands to a script, but I suggest to test them first one by one checking the result after each step.

A script that takes your top level directory as its sole argument, can look like this:

#!/bin/bash
cd "$1"
find . -iname "*.zip" -execdir unzip {} \;
find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;
find . -mindepth 2 -maxdepth 2 -type d -delete
find . -iname "*.zip" -delete

If you give it the name "extract" (and set the execution permission), it can be used in its own directory like this (assuming ~/photos as your top level directory):

./extract ~/photos

But beware: This script was never tested. It also does no tests by its own. It depends on exactly the directory and zip file structure that you describe. So please do copies and test runs.

  • 1
    The logic is fairly sound, but I'm pretty sure this will fail for extracted files with a space in their name. – Sparhawk Jan 17 at 6:47
  • 1
    @Sparhawk: You are so right. I corrected that. (Only the argument of the mv command was affected; the {} are expanded by find and are no subject to word splitting.) – Jürgen Jan 17 at 7:07

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.