Create subfolder when zipping - zip

I have file A, B, C
with only the zip command, I would like to create a zip xxx.zip with this structure:
xxx folder:
A
B
C
Actually what I am doing, because I have found no way in the zip handbook is
mkdir xxx
cp A B C xxx
zip -r xxx.zip xxx
Is there anyway to prevent the cp?

In a other list some one send me a system more efficient that cp : link.
mkdir xxx
ln A B C xxx
zip -r xxx.zip xxx

Related

How to create files with folder names recursively using script?

I have a folder structure that can have x subfolders, like so:
Folder 1
Sub-folder 1
Sub-folder 2
Sub-sub-folder 3
Folder 2
I want to create an empty file that has the name of the sub-folders (with .file appended) in their parent folders, as presented here:
Folder 1
Sub-folder 1.file (newly created file that has the same name as the sister folder)
Sub-folder 1
Sub-folder 2.file (newly created file that has the same name as the sister folder)
Sub-folder 2
Sub-sub-folder 3.file (newly created file that has the same name as the sister folder)
Sub-sub-folder 3
Folder 2
Some folders might have spaces in their names, so I've tried the following but it's not working even though echoing $(dirname $dir)/$dir seems to yield the expected result:
#!/bin/bash
find . -mindepth 1 -type d | while read dir
do
touch $(dirname $dir)/$dir.file
done
What would be the best way to achieve this?
Thank you so much in advance!
post updated to try to be clearer
perhaps you could try:
find . -type d | while IFS= read -r d
do
( cd "$d" && cd .. && touch "$(basename "$d").file" )
done
I have tried with awk, check this if its useful for you.
I am giving .file for file name
realpath Fol*/* | awk '{print "touch "$1".file"}' | sh

Zip a folder named dash

Zip folder which contain a folder named - , it can't be zip
folder structure
~/-
~/b.txt
~/-/a.txt
command
cd ~
zip -r abc.zip .
will stuck
~# zip -r abc.zip .
adding: -
I used strace (read(0)), it seems zip treat the folder as a -(standard input).
how can zip folder which contain a folder which name is dash(-)
You can create zip on this way:
zip -r file.zip -/* b*
I know, its not so elegant but it work.
Or you can use tar on such way:
tar cvf file.tar .

Batch removing a sub folder in several parent folders

In linux, I have a group of folders, that all contain the same sub folder structure. E.g.
FolderA/x/y/z/file1.txt
FolderA/x/y/z/file2.txt
FolderB/x/y/z/file1.txt
FolderC/x/y/z/file1.txt
I want to run a batch process to remove one of the subfolders, but leave all files and folders beneath unchanged. E.g. if I were to remove folder "y":
FolderA/x/z/file1.txt
FolderA/x/z/file2.txt
FolderB/x/z/file1.txt
FolderC/x/z/file1.txt
I've tried putting together some combination of find and mv, but can't quite get it right
find . -name y -type d -exec sh -c '
for d; do echo mv "$d"/* "$d"/..; echo rmdir "$d"; done' _ {} +
Remove the echos if the results look like what you expect.
Considering You want to remove one of the subfolders, but leave all files and folders beneath unchanged, here is something you can do. It's NOT an exact Solution, kind of trick that might work for you. I have done it many times on my computer.
You can recursively copy the subfolder's contents to it's parent folder and then traverse to parent directory and then finally recursively remove the subfolder.
Traverse to subfolder
$ cd path/to/SubFolder
Copy all Contents Recursively to Parent Folder
$ cp -R * ..
Traverse to Parent Folder
$ cd ..
Remove recursively Subfolder
$ rm -rf SubFolder/
Say you have a folder y, then,
$ cd path/to/folder/y
$ cp -R * ..
$ cd ..
$ rm -rf y/
For running a Batch Process You can figure out the path to subfolder using find command.
Notice that this trick can consume a lot of time & resources, If you have a lot of folders in the folders. But that works !

Exclude certain directories from ls and copy the remaining over to a shared path

I have a folder that contains sub-directories A,B,C and D. I need to copy directories A and D to another directory called 'copy' while excluding B and C(i.e. B and C doesn't get copied over). I was thinking about doing the following (in command-line pseudocode):
ls (selective ls on the source directory) |
scp -r {returned value from the ls} {target directory}
Is there a Linux command-line way to accomplish the above?
I'd suggest using find for this.
Let's create some test subjects:
$ mkdir -p ./testing/test{1,2,3,4}
$ touch ./testing/test{1,2,3,4}/test{a,b}
Will result in:
$ ls -R ./testing
./testing:
test1 test2 test3 test4
./testing/test1:
testa testb
./testing/test2:
testa testb
./testing/test3:
testa testb
./testing/test4:
testa testb
Now, run
$ mkdir ./testing/copy
$ find ./testing/ -mindepth 1 -maxdepth 1 ! -name test1 ! -name test3 ! -name copy -execdir cp -R '{}' ./copy/ ';'
Will result in:
$ ls -R ./testing/
./testing/:
copy test1 test2 test3 test4
./testing/copy:
test2 test4
./testing/copy/test2:
testa testb
./testing/copy/test4:
testa testb
./testing/test1:
testa testb
./testing/test2:
testa testb
./testing/test3:
testa testb
./testing/test4:
testa testb
Background information:
Summary: find the directories which need to be copied and execute the copy command. In this case, let's copy all directories but 'test1' and 'test3'.
The -mindepth 1 option will prevent find from including the . and possibly .. directories, since these are on depth 0.
The -maxdepth 1 option will prevent find from copying every single subdirectory individually. The command cp -R handles the subdirectories, so they are covered.
Use -execdir instead of -exec, so you don't have to include the whole path as the target directory for cp command.
DO NOT forget to mkdir your target directory before running find, and DO NOT forget to exclude this directory from the result! Hence the ! -name copy option in my example.
I hope this points you in the right direction.
The simple answer is to only copy the directories you want:
scp -r A D anotherhost:/path/to/target/directory
This will do exactly what you've described in your example. A more general solution might look something like this:
scp -r $(ls | egrep -v '^(B|C)$') anotherhost:/path/to/target/directory
This command will work as long as the number of files in your source directory is not large. As the number of files goes up, you'll eventually run into a "command too long" error.
Instead of using scp, you could use rsync, which has a variety of mechanisms for including/excluding files. For example:
rsync --exclude='B/' --exclude='C/' . anotherhost:/path/to/target/directory
If you really know your directories, simply add all to the scp:
scp A/* D/* targetHost:/copy
The only problem with this solution is, that it "mixes" your files in the copy directory. Probably, it dosen't matter :-)

Deleting a folder that contains symlinks

If I rm -rf a folder that has soft links in it, will it try to follow those links and delete the corresponding folder, or will it simply unlink them?
I have a copy of my home directory with symbolic links in it, and I'm scared to rm -rf it in case it follows those links and blows up the corresponding folders...
Generally speaking, rm doesn't "delete". It "unlinks". This means that references to a file are removed by rm. When the number of references reaches zero, the file will no longer be accessible and in time, the area of disk where it resides will be used for something else.
When you rm a directory, the stuff inside the directory is unlinked. Symbolic links are (sort of like) files with the name of their targets inside them and so they're just removed. To actually figure out what they're pointing to and then unlink the target is special work and so will not be done by a generic tool.
No. rm -rf won't follow symbolic links - it will simply remove them.
% mkdir a
% touch a/foo
% mkdir b
% ln -s a b/a
% rm -rf b
% ls a
foo
Here is axample:
find a b
a
a/1
a/2
b
ll
drwxr-xr-x 2 ****** ****** 4.0K Feb 6 15:11 a
lrwxrwxrwx 1 ****** ****** 1 Feb 6 15:13 b -> a
.
rm -rf b
gives
find a b
a
a/1
a/2
.
rm -rf b/
gives error:
rm: cannot remove `b/': Not a directory
Conclusion:
rm does not follow symlinks
POSIX quote
Since rm -r is POSIX we can also look at what they have to say: https://pubs.opengroup.org/onlinepubs/009604599/utilities/rm.html
The rm utility shall not traverse directories by following symbolic links into other parts of the hierarchy, but shall remove the links themselves.
The rationale section mentions a bit more:
The rm utility removes symbolic links themselves, not the files they refer to, as a consequence of the dependence on the unlink() functionality, per the DESCRIPTION. When removing hierarchies with -r or -R, the prohibition on following symbolic links has to be made explicit.

Resources