I have these zip files:


And I need each zip extracted into its appropriate directory with this format (basically, I only need the first 30 characters):


This is the command I currently have, which works but only for the second zip file (PLP_634562_2004-03-02_02-15-07_UBIC.zip)

for f in /PLP*.zip; do n=$(echo $f | cut -f 1-5 -d '_'); unzip -d $n $f;done

I would like to change it so that it reads only the first 30 characters of the zip file and then creates the directory based on that. It will ensure any new zip file naming format will work in the future.

I've tried changing the n variable part of the command to this

n=$(echo ${f:0:30}); 

but that didn't work. I'm using Linux bash.

  • You should simply run for f in PLP*.zip; do unzip -d "${f:0:30}" "$f"; done in the directory where you have those files. Your solution doesn't work as expected because you're using for f in /PLP*.zip so the value of f is the filename + a leading slash. In that case you'd have to to adjust parameter expansion to ${f:0:31} (who keeps zip files in the root directory ?) May 19 '16 at 20:07

With sed you can get the first 30 characters:

sed 's|\(.\{30\}\).*|\1|'

and use that instead of cut in your for loop.

The breakdown of that sed substitution is that what is matched between \( \) you substitute with \1. the {30} (escaped with \) counts 30 single characters (.).

  • This is the thing, I just realized my current solution works because it looks for patterns, therefore it finds the zip file name without including the file information. With the sed solution, what ends up happening is that the first 30 characters are grabbed which includes the file information "-rw-r--r-- 1 user123 usr 43525" Should I edit my question? May 19 '16 at 20:13
  • Why would you edit your question? You seem to be using ls -l so just don't use find to get the list of filenames.
    – Anthon
    May 19 '16 at 20:57
  • @LatinCanuck It seems you do not understand what * actually means. Try set -x; ls /PLP*.zip. May 20 '16 at 7:33

Thanks for all the suggestions, I took pieces from everyone's suggestions and built this command. In my case this is exactly the command I required.

for f in /mydirectory/*.zip; do
   n=$(echo ${f##*/} | cut -c1-30);
   unzip -d /mydirectory/$n $f;
  • It loops through all the zip files
  • Echos each zip file (file name only, no extra info like size or path is displayed) and then only shows the first 30 characters & stores it in n variable
  • It then extracts content into a new directory (using n variable) for each zip file.

In my case, I put this in a script that runs from another directory.

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.