2

I have many zip files in a folder, such as:

abc.zip, xyz.zip, ...., etc.

I want to unzip these files, but into the folders with the same names:

abc, xyz, ..., etc.

I do like this:

unzip '*.zip'

or

for i in folder; do unzip $i; done

It doesn't work, because it will extract all contents of these zip files into a folder.

Can you help? Thanks. PS: I am using Mac

chipbk10
  • 5,783
  • 12
  • 49
  • 85
  • Does the Mac unzip have a "-d" (extract files into exdir) option? If so, you should be able to do `for f in ``ls *.zip``; do mkdir "${f%.*}"; unzip $f -d "${f%.*}"; done`. If there is not a "-d", then do a cd into the directory and then cd back after the zip. (the double backtick should be single, but the code paste didn't support it). – KevinO Mar 23 '16 at 13:57
  • DO NOT USE `ls` output for anything. ls is a tool for interactively looking at directory metadata. Any attempts at parsing `ls` output with code are broken. Globs are much more simple AND correct: `for file in *.txt. Read [Parsing ls](http://mywiki.wooledge.org/ParsingLs) – Rany Albeg Wein Mar 23 '16 at 14:01
  • @RanyAlbegWein, you are correct that `ls` output can be problematic. But let's not go so far as to say **any** attempts are broken. – KevinO Mar 23 '16 at 14:07
  • If you know the environment well enough to take the risk and execute such a script that uses `ls` as its source of input, then that's fine. The problem is that you *never* know the environment well enough, especially when you share code across the web. Your code is broken. To figure out why you don't want to use it on your system, or share it with others, read [Parsing ls](http://mywiki.wooledge.org/ParsingLs). – Rany Albeg Wein Mar 23 '16 at 14:22
  • @KevinO, add quotations to $f in order for it to respect spaces with ``` for f in ``*.zip``; do mkdir "${f%.*}"; unzip "$f" -d "${f%.*}"; done ``` – ionush Jul 16 '23 at 02:41

1 Answers1

4

Quoted from man unzip of version UnZip 6.00 of 20 April 2009, by Info-ZIP. Maintained by C. Spieler.

  [-d exdir]
          An  optional  directory  to  which  to extract files.  By default, all files and subdirectories are recreated in the current directory; the -d option allows extraction in an arbitrary directory
          (always assuming one has permission to write to the directory).  This option need not appear at the end of the command line; it is also accepted before the zipfile specification (with the  nor‐
          mal options), immediately after the zipfile specification, or between the file(s) and the -x option.  The option and directory may be concatenated without any white space between them, but note
          that this may cause normal shell behavior to be suppressed.  In particular, ``-d ~'' (tilde) is expanded by Unix C shells into the name of the user's home directory, but ``-d~'' is treated as a
          literal subdirectory ``~'' of the current directory.

Never used unzip, but it seems like it is possible to run the following:

for f in dir/*.zip; do
    # Creating a name for the new directory.
    new_dir="${f##*/}"
    new_dir="${new_dir%.*}"
    # Creating the directory if it doesn't already exist.
    mkdir -p "$new_dir"
    # Unzip contents of "$f" to "$new_dir"
    unzip -d "$new_dir" -- "$f"
done

Which will iterate over all zip files inside a directory called dir, create a new directory inside the present-working-directory (or PWD) named after the base-name of the zip file - if doesn't already exist, and will unzip the contents of the zip file to the created or already exists directory.


Let's test it:

Inside a directory called test I created two archives: a.zip and b.zip.

a.zip contains the files 1.txt, 2.txt and 3.txt.

b.zip contains the files 4.txt, 5.txt and 6.txt.

for f in test/*.zip; do new_dir="${f##*/}"; new_dir="${new_dir%.*}"; mkdir -p "$new_dir"; unzip -d "$new_dir" -- "$f";done
Archive:  test/a.zip
extracting: a/1.txt                 
extracting: a/2.txt                 
extracting: a/3.txt                 
Archive:  test/b.zip
extracting: b/4.txt                 
extracting: b/5.txt                 
extracting: b/6.txt
Rany Albeg Wein
  • 3,304
  • 3
  • 16
  • 26