11

I want to zip a sub directory and send it elsewhere, the problem I have is when I use the zip command it also includes all the unwanted layers of directories I do not want.

e.g.

zip -r /new.zip /Unwanted1/Unwanted2/wanted1/wanted2/file.txt

###unzipped produces the following
/Unwanted1/Unwanted2/wanted1/wanted2/file.txt

###I want
/wanted1/wanted2/file.txt

update: The directory I want to zip has lots of nested directories, hence the -r. Also it would be great to deal with absolute paths, the old solution used to cd about the place but I just didn't really like it. Perhaps that is the best (only) way.

henry.oswald
  • 5,304
  • 13
  • 51
  • 73
  • The `-r` means recursive. If you really need to use that, then you should read up on the zip options for exclude. If you just want to zip one file, cd to the appropriate parent dir (per your example) ./Unwanted1/Unwanted2 and then `zip new.zip wanted/file.txt`. That is to say, I don't think there is a zip option that means 'discard the first n layers of subdirectory info on the input filename'. Good luck. – shellter Nov 17 '11 at 22:05
  • You've since edited your example, which changes the game a fair amount. People don't usually want absolute paths like that. There might be more path trim/control options inside 'zip' but I doubt it. Read the man page. Or switch to 'tar' and read that (equally long) man page. And you still don't need -r if you're adding a single file, no matter how deep. – IcarusNM Nov 19 '11 at 00:33

3 Answers3

18

You have to change directories to wherever you want to start, or maybe there's an option to 'zip' to do that for you. If you're too lazy to read through the gazillion options in the man page, like I am, just 'cd' first, even in a script. Or you can enclose the whole thing in parenthesis without affecting your shell or script's working directory:

(cd Unwanted1/Unwanted2; zip -r ~/new.zip ./wanted/file.txt)

Or since you're using -r you presumably want more than just file.txt, so:

(cd Unwanted1/Unwanted2; zip -r ~/new.zip wanted)

Or use pushd/popd to jump in/out:

pushd Unwanted1/Unwanted2
zip -r ~/new.zip wanted
popd

This works in sh/bash/csh/tcsh.

IcarusNM
  • 951
  • 7
  • 16
3

Simplest, idiomatic way:

(cd ./Unwanted1/Unwanted2 && zip -r ../../new.zip ./wanted/file.txt)

Now zip, tar, rar, cpio and friends all have options to manage the same, but they may differ from version to version and certainly from archive utility to archive utility. I suggest you learn to work with the shell to do the work, and you can use any archive format you desire

Another way:

(cd ./Unwanted1/Unwanted2 && find . -name "*.txt" -print) | zip new.zip -@
sehe
  • 374,641
  • 47
  • 450
  • 633
  • As much as I would prefer a flag/option in `zip` to omit the parent folder structure, there doesn't appear to be a better way that this. Both flags `-j` or `-D` didn't do what we wanted on a complex sub-folder structure. – paperclip Dec 07 '16 at 11:57
3

Well one simple way around might be to do

cd ./Unwanted1/Unwanted2
zip -r ../../new.zip ./wanted/file.txt

But I don't know what your situation is. Perhaps you're required to run from the base directory? Also the "-r" option is used when you want to recursively traverse directories - the example you provided is using one file.

loosebazooka
  • 2,363
  • 1
  • 21
  • 32
  • Thanks it is actually multiple directories and files, example is v.simple – henry.oswald Nov 17 '11 at 22:20
  • Yeah so like icarus and sehe say, if you enclose the commands in parenthesis, it doesn't mess up your current working directory after it's finished executing. – loosebazooka Nov 18 '11 at 01:29