Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all zips, and unzip in place - Unix

I have been trying for some time and believe I am fairly close to this, but I am fairly new to Unix so have been finding this difficult.

I have a folder, containing many folders, some of which have zip files in them, some which don't. I am trying to unzip all of the zip files in any sub directories in place.

For example I have:

files/A/something.java

files/B/somezipfile.zip

files/C/someotherfile.zip

files/D/AnotherZipFile.zip

I would like to unzip them (assuming the zips contain just .java files), to have a result like: files/A/something.java

files/B/javafile.java

files/C/someotherfilefromzip.java

files/D/Anotherfile.java

I don't mind if the ZIP files remain or are deleted after unzipping, either is fine.

What I have tried so far.

1) I expected I could use piping, which I am new to, like this:

find . -name *.zip | unzip

This doesn't work.

2) I spent some time searching, the closest I got using a solution online is:

find . -name '*.zip' -exec unzip '{}' ';'

This unzips, but unzips them into the current working directory, I wanted them to unzip in place. I also don't understand this command which I would like to as I am trying to learn.

Any help is much appreciated.

Thanks,

like image 685
ThePerson Avatar asked Feb 11 '13 13:02

ThePerson


People also ask

How do I extract all zip files at once?

To unzip a single file or folder, open the zipped folder, then drag the file or folder from the zipped folder to a new location. To unzip all the contents of the zipped folder, press and hold (or right-click) the folder, select Extract All, and then follow the instructions.

How do I search for a zip file in Unix?

zipgrep will work with zip files only. If you want to grep all files, not only zipped files, then you could use ugrep, which allows to do that with -z flag.


2 Answers

find . -name '*.zip' -exec sh -c 'unzip -d `dirname {}` {}' ';'

This command looks in current directory and in its subdirectories recursively for files with names matching *.zip pattern. For file found it executes command sh with two parameters:

-c

and

unzip -d `dirname <filename>` <filename>

Where <filename> is name of file that was found. Command sh is Unix shell interpreter. Option -c tells shell that next argument should be interpreted as shell script. So shell interprets the following script:

unzip -d `dirname <filename>` <filename>

Before running unzip shell expands the command, by doing various substitutions. In this particular example it substitutes

`dirname <filename>`

with output of command dirname <filename> which actually outputs directory name where file is placed. So, if file name is ./a/b/c/d.zip, shell will run unzip like this:

unzip -d ./a/b/c ./a/b/c/d.zip

In case you ZIP file names or directory names have spaces, use this:

find . -name '*.zip' -exec sh -c 'unzip -d "`dirname \"{}\"`" "{}"' ';'
like image 74
Mikhail Vladimirov Avatar answered Sep 20 '22 08:09

Mikhail Vladimirov


Use -execdir instead of -exec, which runs the command in the directory where the file is found, not the directory you run find from.

find . -name '*.zip' -execdir unzip '{}' ';'
like image 30
chepner Avatar answered Sep 21 '22 08:09

chepner