How to create a zip file without entire directory structure - linux

I am trying to create a zip file and want to preserve most of the directory structure, but not the rootdir as defined from the command line. The command I'm using is:
zip -r out.zip /foo/bar/
I'd like it to recurse through bar and add all files with preserved directory structure (which it does). However I do not want 'foo' to be the top level directory in the zip file created. I would like bar to be the top level directory.
Is there any easy way to go about this? I realize I could change directories before zipping to avoid the problem, but I'm looking for a solution that doesn't require this.

This should do it:
cd /foo/bar/
zip -r ../out.zip *
The archive will be in /foo/out.zip

I don't believe zip has a way to exclude the top level directory. I think your best bet would be to do something like:
pushd /foo; zip -r out.zip ./bar; popd;
But this is exactly the sort of answer you said you didn't want.

7z a -tzip out.zip -w foo/bar/.

If someone stumbles upon this and is not satisfied with the above solution, here follows a very simple workaround to not zip long subdirectories. It involves temporarily creating a folder in C:/, and after zipping simply deleting it:
ZipFiles <- list.files(".../ZipFiles") # Insert your long subdirectory into .../
dir.create("C:/ZipFiles")
dir.create(".../FolderToBeZipped")
file.copy(from = ZipFiles,to = "C:/ZipFiles")
zip(".../FolderToBeZipped",
files = "C:/ZipFiles")
unlink("C:/ZipFiles",recursive = TRUE)
The result then is .../FolderToBeZipped.zip/ZipFiles/
The benefit is that you need not be within the subdirectory (or project) when executing the code.

Related

How do I copy differing content files from one directory to another?

There exists two directories: a/ and b/.
I'd like to copy all the files(recursively) from a/ into b/.
However, I only want to copy over an a file if its content is different than the already existing b file. If the corresponding b file does not exist, then you would still copy over the a file.
*by "corresponding file", I mean a files with the same name and relative path from their parent directories.
note:
The reason I don't want to overwrite a b file with the same exact contents, is because the b directory is being monitored by another program, and I don't want the file date to change causing the program to do more work than required.
I'm essentially looking for a way to perform a cp -rf a/ b/ while performing a diff check on each file. If the file's are different, perform the copy; otherwise skip the copy.
I see that cp has an update flag:
-u, --update
copy only when the SOURCE file is newer than the destination file or when the
destination file is missing
but this will not work because I'm not concerned about newer files; I'm concerned about different file contents.
Any shell language will do.
I've been attempting to get this to work by injecting my diff check into a find command:
find a/ ??? -exec cp {} b \;
This doesn't seem like an uncommon thing to do between two directories, so I'm hoping there is an elegant command line solution as aposed to me having to write a python script.
You can achieve this using rsync. Files or directories will be updated only if there is any new update in source folder.
$rsync -av --progress sourcefolder destinationfolder

How to use command zip in linux that folder have short path?

I used command zip in linux (RedHat), this is my command:
zip -r /home/username/folder/compress/zip.zip /home/username/folder/compressed/*
Then, i open file zip.zip, i see architecture as path folder compress.
I want to in folder zip only consist list file *.txt
Because i used this command in script crontab hence i can't use command cd to path folder before run command zip
Please help me
I skimmed the zip man page and this is what I have found. There is not an option archive files relative to a different directory. The closest I have found is zip -j which removes the entire path and stores the files directly in the zip rather than sub directories. I do not know what happens in the case of file name conflicts such as if /home/username/folder/compressed/a.txt and /home/username/folder/compressed/subdir/a.txt both exist. If this is not a problem for you, you can use this option, but I am concerned because you did specify the -r option indicating that you expect zip to traverse sub folders.
I also thought of the possibility that your script could somehow call zip with a different working directory, but I took a look at this unix stack exchange page and it looks like their options use cd.
I have to admit I do not understand why you cannot use cd and I am very curious about it. You said something about using crontab, but I have never heard of anything wrong with changing directories in a crontab script.
I used option -j in command zip
zip -jr /home/username/folder/compress/zip.zip /home/username/folder/compressed/*
and i was yet settled this problem, thanks

Unzip archive to an existing directory structure

I'm looking at bring the content of one WP blog over to another as I will be using WPML to server regional content instead of multiple sites. So not strictly a WP question, more command line.
This may seem an obvious or stupid question, but if I bring over the other 'uploads' folder as a zip and unzip to the wp-content folder, will the contents merge into the existing folders or overwrite what is already there.
If it's the latter, is there a switch I can append to ensure files are merged?
Thanks in advance,
Tom
When unzip finds a file that already exists in the destination, it will ask you if you want to overwrite it. You can then type y to overwrite it, A to overwrite all files, N if you don't want to overwrite any of them etc.
Example:
$ unzip archive.zip
Archive: archive.zip
replace foo? [y]es, [n]o, [A]ll, [N]one, [r]ename:
Try using
unzip -o <filepath/zipfile.zip> -d <path where you want files>
Best use: unzip --help

How to repack zip files without using tmp dir?

I have a lot of zip files that I need to repack/recompress in order to work around a bug in MediaWiki 0.1.18.
I can do it with
#!/bin/bash
for f in *zip; do
cd tmp
rm -rf *
unzip ../"$f"
zip -r ../"$f" *
cd ..
done
but is there a way to do this e.g. with pipes or perhaps a zip option?
gzip -d -c old.gz | gzip >new.gz
There is a utility called AdvanceCOMP that does exactly what you're looking for. It recompresses ZIP and GZ files (and some others) without intermediary extraction to disk. (I do believe that the mechanism used is to decompress the data and recompress it, but that does not require writing files to disk or regenerating metadata.)
You can't. If you send some bits to zip it doesn't have a way to know when one file ends and a new one begins.
Actually you can write your own program to do the job but from your description it seems like an overkill. Also you are not telling what exactly bug are you fixing so other workarounds cannot be suggested.
A bit late, but it may be helpfull for those who come later:
zipsplit -n 2147483648 will repack zip upto 2GiB without extraction. But as this command is for splitting zip files, there is no option to overwrite original or specify output file, only output directory.

how to copy between folders and parent folder without complete path

This is a basic question but I am struggling to find a decent solution. This is hindering my script from automation.
I have the following path.
/home/hassan/Dyna/ProjectSimulation
in project simulation I have 3 folders
friction time force
like
/home/hassan/Dyna/ProjectSimulation/friction
Now I have a file friction1.txt in this friction folder and I want to copy it to ProjectSimulation.
is it possible to avoid complete path and just one step down?
Also if I have to copy this friction1.txt to folder force, is there anyway to avoid the complete path.
I mean I have a subroutine but this is path dependent , whenever I run it , I have to run in the same folder and then copy my results so I can run only one instance of my simulation.
Experts please guide me.
PS: This is part of a 600 lines shell.
This comes across as so basic that I must have misunderstood something in your question.
If you want to refer to a parent directory, .. is the way to do that. So, if you want to copy friction1.txt to two places you just do
cp friction1.txt ..
cp friction1.txt ../force
All you need to take care of is making sure that CWD is
/home/hassan/Dyna/ProjectSimulation/friction
so that the references point at the right place.
You can temprarily change the current directory to ProjectSimulation, copy the file (cp friction/friction1.txt .), then change the path back to the original (so the rest of the script works as before)
Alternatively, you can use dirname to get he name of the parent directory and use that.
Change to the root dir of your known directory structure. Then do the copy operations with relative paths. Then change back to your dir where you came from.
Your friends are:
cd
cd -
or better:
pushd
popd
(see man bash)
I.e.
pushd /home/hassan/Dyna/ProjectSimulation
cp friction/friction1.txt .
cp friction/friction1.txt force
popd

Resources