LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-05-2012, 11:18 AM   #1
IlIl7
LQ Newbie
 
Registered: Oct 2010
Location: Europe mainly.. :D
Distribution: BackTrack 5
Posts: 17

Rep: Reputation: 0
command to unzip multiple subfolders


Hi all
I have several (more than 10000 ) folders lets call them A,B,C,D..... all located inside the directory
Code:
/home/somestuff.
Each one of these folders contains 1 or more zip files.
E.g.
Code:
Folder A contains aa1.zip aa2.zip (if extracted they give aaa file)
     Folder B contains bbb.zip (if extracted it gives bbb file)
....
     Folder P contains pp1.zi pp2.zip pp3.zip pp4.zip (if extracted they give ppp file)
and so on...
i want to extract the content of these zip files to each parent directory using command line.
I tried so far several commands with no sucess.
I run the following command from /home/somestuff:
Code:
find . -depth  -name '*.zip' -type f | xargs -I '{}' unzip -o '{}'
the problem with that is that i get all the files extracted but not inside their corresponding folders but inside somestuff....

Any idea what to change to achieve the desired result?

thanks everybody for your time!
 
Old 07-05-2012, 12:02 PM   #2
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Perhaps:

Code:
find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}' -d "$(dirname {})"
 
1 members found this post helpful.
Old 07-05-2012, 12:26 PM   #3
IlIl7
LQ Newbie
 
Registered: Oct 2010
Location: Europe mainly.. :D
Distribution: BackTrack 5
Posts: 17

Original Poster
Rep: Reputation: 0
Quote:
Perhaps:

Code:

find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}' -d "$(dirname {})"
But i have about 10000 folders...how can i go though all of them without having to typing
Quote:
dirname
each time???
 
Old 07-05-2012, 01:46 PM   #4
rbdharnia
LQ Newbie
 
Registered: Nov 2010
Location: haryana,india
Distribution: fedora
Posts: 5

Rep: Reputation: 0
http://linuxhelp-rbdharnia.rhcloud.c...p?namex=gunzip
 
Old 07-05-2012, 02:12 PM   #5
IlIl7
LQ Newbie
 
Registered: Oct 2010
Location: Europe mainly.. :D
Distribution: BackTrack 5
Posts: 17

Original Poster
Rep: Reputation: 0
@rbdharnia

thanks for your answer but it ..doesnt help me at all...i can read this in a shell ..with gzip --help...
 
Old 07-05-2012, 02:28 PM   #6
custangro
Senior Member
 
Registered: Nov 2006
Location: California
Distribution: Fedora , CentOS , RHEL
Posts: 1,979
Blog Entries: 1

Rep: Reputation: 209Reputation: 209Reputation: 209
Try this...


Code:
find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}' -d "$(basename {} .zip)"
Note that there is a SPACE between the {} and the .zip
 
Old 07-05-2012, 02:29 PM   #7
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,148
Blog Entries: 2

Rep: Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886Reputation: 4886
Quote:
Originally Posted by IlIl7 View Post
But i have about 10000 folders...how can i go though all of them without having to typing each time???
You don't have to. dirname is a command, just type literally dirname in that command.
 
Old 07-05-2012, 03:39 PM   #8
IlIl7
LQ Newbie
 
Registered: Oct 2010
Location: Europe mainly.. :D
Distribution: BackTrack 5
Posts: 17

Original Poster
Rep: Reputation: 0
@custangro unfortunatelly the folowing:
Quote:
find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}' -d "$(basename {} .zip)"
gives me the following error for al zip files:
Quote:
....
cannot create extraction directory: bbb.zip
File exists
....
//-----------------------------------------------------------------------------------------------------//
@TobiSGD thanks for explaining me that about dirname but the following:
Quote:
find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}' -d "$(dirname {})"
does extract the files but NOT EACH ONE INSIDE ITS INITIAL SUBFOLDER LIKE DESIRED BUT ALL OF THEM ARE EXTRACTED INSIDE THE PARENTFOLDER WHICH IS somestuff
so the above has the same result like mine:
Quote:
find . -depth -name '*.zip' -type f | xargs -I '{}' unzip -o '{}'
//-----------------------------------------------------------------------------------------------------//
I repeat i want a command which i will run while on somestuff. This should cause all zip files that are inside the subfolders of sumestuff to extract their contents INSIDE EACH CORRESPONDING SUBFOLDER. The last 2 commands above run well ONLY IF I RUN THEM WHILE IN EACH SUBFOLDER....that means i should do this about 10000 ..times...
i hope u make sense with my english...
 
Old 07-05-2012, 04:25 PM   #9
lithos
Senior Member
 
Registered: Jan 2010
Location: SI : 45.9531, 15.4894
Distribution: CentOS, OpenNA/Trustix, testing desktop openSuse 12.1 /Cinnamon/KDE4.8
Posts: 1,144

Rep: Reputation: 217Reputation: 217Reputation: 217
Hi,

I would like to show you the possibility to extract to the directory according to filename, but I used 7za.
I know it's not full script like you would like to have, but for the test I have in the directory 2 zip files which contain files with subdirectories:
Code:
ls
total 104
drwxr-xr-x 4 lithos users  4096 jul  5 23:11 ./
drwxrwxrwt 9 root   root   4096 jul  5 22:47 ../
-rw-r--r-- 1 lithos users 82944 jul  5 22:49 aaa.zip
-rw-r--r-- 1 lithos users  4085 jul  5 22:49 bb.zip
then I wanted to extract all files *.zip to directories with the filename, like:
Code:
aaa.zip -> aaa/files from archive with subdirectories
bb.zip --> bb/files -||-
so I did this to get the "directory names from filename":
Code:
for file in *.zip; do echo "$(echo $file | cut -d\. -f 1)"; done
aaa
bb
and the complete command is:
Code:
for file in *.zip; do mkdir "$(echo $file | cut -d\. -f 1)" && 7za x $file -o"$(echo $file | cut -d\. -f 1)"; done        <---  -o sets the output directory

7-Zip (A) 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,1 CPU)

Processing archive: aaa.zip

Extracting  cgi-bin
Extracting  cgi-bin/htsearch
Extracting  cgi-bin/info2html
Extracting  cgi-bin/info2html.conf
Extracting  cgi-bin/infocat
Extracting  cgi-bin/qtest

Everything is Ok

Folders: 1
Files: 5
Size:       206930
Compressed: 82944

7-Zip (A) 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,1 CPU)

Processing archive: bb.zip

Extracting  htdocs
Extracting  htdocs/favicon.ico
Extracting  htdocs/gif
Extracting  htdocs/gif/l_arrow.gif
Extracting  htdocs/gif/r-ball.gif
Extracting  htdocs/gif/r_arrow.gif
Extracting  htdocs/gif/r_hand.gif
Extracting  htdocs/gif/u_arrow.gif
Extracting  htdocs/index.html
Extracting  htdocs/index.php
Extracting  htdocs/info2html.css
Extracting  htdocs/robots.txt

Everything is Ok

Folders: 2
Files: 10
Size:       4701
Compressed: 4085
And I get in the current directory:
Code:
ls -R aaa
aaa:
total 12
drwxr-xr-x 3 lithos users 4096 jul  5 23:11 ./
drwxr-xr-x 4 lithos users 4096 jul  5 23:11 ../
drwxr-xr-x 2 lithos users 4096 jul  5 23:11 cgi-bin/

aaa/cgi-bin:
total 220
drwxr-xr-x 2 lithos users   4096 jul  5 23:11 ./
drwxr-xr-x 3 lithos users   4096 jul  5 23:11 ../
-rwxr-xr-x 1 lithos users 121004 okt 29  2011 htsearch*
-rwxr-xr-x 1 lithos users  26284 okt 22  2011 info2html*
-rw-r--r-- 1 lithos users   3233 okt 22  2011 info2html.conf
-rwxr-xr-x 1 lithos users   5381 okt 22  2011 infocat*
-rwxr-xr-x 1 lithos users  51028 okt 29  2011 qtest*
I hope this helps you.
 
1 members found this post helpful.
Old 07-05-2012, 05:46 PM   #10
sag47
Senior Member
 
Registered: Sep 2009
Location: Raleigh, NC
Distribution: Ubuntu, PopOS, Raspbian
Posts: 1,899
Blog Entries: 36

Rep: Reputation: 477Reputation: 477Reputation: 477Reputation: 477Reputation: 477
If you want a simple shell script you can place this in the root directory of the file structure you're working with. This is the combined ideas of other posts in this thread. I tested it with a sample set and it works on my system. Just change the $rootdir variable if you want to set your own path and run the script elsewhere. Use full path name and not relative.
Code:
#!/bin/bash
rootdir="$PWD"
find "$rootdir" -type f -name '*.zip' | while read file;do
  cd "$(dirname "$file")"
  if [ "$(dirname "$file")" = "$PWD" ];then
    unzip "$file"
  else
    echo "error"
    break
  fi
done
cd "$rootdir"
It unzips zip files relative to the path of the actual zip file. The script accounts for folders with spaces in them as well.

Alternatively, you can delete the zip files after successfully determining the exit code of unzip (i.e. delete only if extraction was successful).

Note: The parenthesis are not supposed to be escaped when inside of $()

SAM

Last edited by sag47; 07-05-2012 at 05:57 PM.
 
1 members found this post helpful.
Old 07-05-2012, 06:08 PM   #11
lithos
Senior Member
 
Registered: Jan 2010
Location: SI : 45.9531, 15.4894
Distribution: CentOS, OpenNA/Trustix, testing desktop openSuse 12.1 /Cinnamon/KDE4.8
Posts: 1,144

Rep: Reputation: 217Reputation: 217Reputation: 217
Quote:
Originally Posted by sag47 View Post
... It unzips zip files relative to the path of the actual zip file. The script accounts for folders with spaces in them as well.
and you get:
Code:
ls
total 108
drwxr-xr-x 4 lithos users  4096 jul  6 00:42 ./
drwxrwxrwt 9 root   root   4096 jul  5 23:37 ../
-rw-r--r-- 1 lithos users 82944 jul  5 22:49 aaa.zip
-rw-r--r-- 1 lithos users  4085 jul  5 22:49 bb.zip
-rwxr-xr-x 1 lithos users 121004 okt 29  2011 htsearch*
-rwxr-xr-x 1 lithos users  26284 okt 22  2011 info2html*
-rw-r--r-- 1 lithos users   3233 okt 22  2011 info2html.conf
-rwxr-xr-x 1 lithos users   5381 okt 22  2011 infocat*
-rwxr-xr-x 1 lithos users  51028 okt 29  2011 qtest*
instead of
Code:
-rw-r--r-- 1 lithos users 82944 jul  5 22:49 aaa.zip
-rw-r--r-- 1 lithos users  4085 jul  5 22:49 bb.zip
aaa/htsearch*
aaa/info2html*
aaa/info2html.conf
aaa/infocat*
aaa/qtest*
which I believe is what OP wanted.
 
Old 07-05-2012, 11:46 PM   #12
sag47
Senior Member
 
Registered: Sep 2009
Location: Raleigh, NC
Distribution: Ubuntu, PopOS, Raspbian
Posts: 1,899
Blog Entries: 36

Rep: Reputation: 477Reputation: 477Reputation: 477Reputation: 477Reputation: 477
Quote:
Originally Posted by lithos View Post
instead of
Code:
-rw-r--r-- 1 lithos users 82944 jul  5 22:49 aaa.zip
-rw-r--r-- 1 lithos users  4085 jul  5 22:49 bb.zip
aaa/htsearch*
aaa/info2html*
aaa/info2html.conf
aaa/infocat*
aaa/qtest*
which I believe is what OP wanted.
There's not much to change to get the desired method. Also the OP's first post was not clear about that. I see in subsequent posts they clarify what they want though. At any rate here's the revised script.

Code:
#!/bin/bash
rootdir="$PWD"
find "$rootdir" -type f -name '*.zip' | while read file;do
  cd "$(dirname "$file")"
  if [ "$(dirname "$file")" = "$PWD" ];then
    mkdir "$(basename "$file" | cut -d. -f1)"
    cd "$(basename "$file" | cut -d. -f1)"
    unzip "$file"
  else
    echo "error"
    break
  fi
done
cd "$rootdir"
Added two lines and now it solves what the OP describes from what I can tell.

SAM
 
1 members found this post helpful.
Old 07-06-2012, 01:40 AM   #13
IlIl7
LQ Newbie
 
Registered: Oct 2010
Location: Europe mainly.. :D
Distribution: BackTrack 5
Posts: 17

Original Poster
Rep: Reputation: 0
THANKS EVERYBODY FOUR TIME!!!!!!!!!
Especially the last 2 commenters (lithos & sag47) for their help!!!!

@sag47
Your last script:
Quote:
#!/bin/bash
rootdir="$PWD"
find "$rootdir" -type f -name '*.zip' | while read file;do
cd "$(dirname "$file")"
if [ "$(dirname "$file")" = "$PWD" ];then
mkdir "$(basename "$file" | cut -d. -f1)"
cd "$(basename "$file" | cut -d. -f1)"
unzip "$file"
else
echo "error"
break
fi
done
cd "$rootdir"
DOES EXACTLY WHAT I WANTED!!!
However I would be grateful if you could add some comments to each line so that i learn as well besides getting the job done
I dont understand why mkdir is needed since the subdirectories exist!!!
 
Old 07-06-2012, 01:46 AM   #14
lithos
Senior Member
 
Registered: Jan 2010
Location: SI : 45.9531, 15.4894
Distribution: CentOS, OpenNA/Trustix, testing desktop openSuse 12.1 /Cinnamon/KDE4.8
Posts: 1,144

Rep: Reputation: 217Reputation: 217Reputation: 217
Quote:
Originally Posted by IlIl7 View Post
......

However I would be grateful if you could add some comments to each line so that i learn as well besides getting the job done
I dont understand why mkdir is needed since the subdirectories exist!!!
But what if it doesn't exist ? It doesn't "hurt" to create it, otherwise Unzip command would fail.

About the script:
Code:
#!/bin/bash
rootdir="$PWD"
find "$rootdir" -type f -name '*.zip' | while read file;do         # find all .zip files in the directory
cd "$(dirname "$file")"
if [ "$(dirname "$file")" = "$PWD" ];then                      # if the file found is in the same directory as defined "rootdir"
mkdir "$(basename "$file" | cut -d. -f1)"
cd "$(basename "$file" | cut -d. -f1)"
unzip "$file"                                                  # unzip the file
else
echo "error"
break
fi
done
cd "$rootdir"
that's about it.
 
2 members found this post helpful.
Old 07-06-2012, 02:58 AM   #15
zhjim
Senior Member
 
Registered: Oct 2004
Distribution: Debian Squeeze x86_64
Posts: 1,748
Blog Entries: 11

Rep: Reputation: 233Reputation: 233Reputation: 233
Just some addition if one wants to use solely find


Code:
 -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.  This a much more secure method for invoking commands, as
              it avoids race conditions during resolution of the paths to the matched files.  As with the -exec action, the `+' form of -execdir will build a command line to process more than one matched file, but any given invoca‐
              tion  of  command will only list files that exist in the same subdirectory.  If you use this option, you must ensure that your $PATH environment variable does not reference `.'; otherwise, an attacker can run any com‐
              mands they like by leaving an appropriately-named file in a directory in which you will run -execdir.  The same applies to having entries in $PATH which are empty or which are not absolute directory names.
taken from man find
 
2 members found this post helpful.
  


Reply

Tags
command line


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Unzip multiple zip files, each to separate folder smart_sagittari Linux - Newbie 3 03-21-2012 08:41 AM
What command to delete all files and subfolders, but not root folder ? proleader Linux - Newbie 10 09-16-2011 05:02 AM
[SOLVED] How to copy a file to all subfolders in a directory using a single command? SirTristan Linux - Newbie 7 07-18-2010 11:19 PM
[SOLVED] extracting multiple files into subfolders ebolamayinga Linux - Software 2 10-02-2009 04:47 PM
How to Unrar/unzip multiple archives at once containing a single file? SentralOrigin Linux - Software 11 11-30-2006 05:57 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 06:07 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration