Search code examples
bashunzip

Unzip fails when specifying keyword


I need to unzip files matching a specific keyword in the name. A typical file will look like this:

JGS-Memphis~PSU~FVT~00000~JGM96911~1~P~1100~EPS10R0-15~CL10D1120A3271~0121017~141645.XML

When I do

unzip -o SOMEFILE.zip '*~PSU~*' -d psutmp/

It unzips the file above from SOMEFILE.zip without problem. But when I do

for i in `find . -name '*zip'`; do  unzip -o "$i" \'*PSU*\' -d psutmp/ ; done

It fails with a filename not matched: '*PSU*' error. I tried removing the tick marks around PSU. Same problem.

I also tried the -C option to match filenames case-insensitively

for i in `find . -name '*XML*zip'`; do  unzip -o "$i" -C *PSU* -d psutmp/ ; done

It fails with a

error:  cannot create psutmp/JGS-Memphis~PSU~FVT~00000~JGM96911~1~P~1100~EPS10R0-15~CL10D1120A3271~0121017~141645.XML

This is bunk. I am the root user of a development machine with 150GB of storage. Capacity is at 12%. What am I missing?


Solution

  • Remove the backslashes in \'*P5U*\'. You don't need to escape the single quotes.

    for i in `find . -name '*zip'`; do  unzip -o "$i" '*PSU*' -d psutmp/ ; done
    

    Using backticks in a for loop is somewhat of a code smell. I'd try one of these instead:

    # Unzip can interpret wildcards itself instead of the shell
    # if you put them in quotes.
    unzip -o '*.zip' '*PSU*' -d psutmp/
    
    # If all of the zip files are in one directory, no need for find.
    for i in *.zip; do unzip -o "$i" '*PSU*' -d psutmp/; done
    
    # "find -exec" is a nice alternative to "for i in `find`".
    find . -name '*.zip' -exec unzip -o {} '*PSU*' -d psutmp/ \;
    

    As far as the error goes, does psutmp/ exist? Are the permissions set so you can write to it?