copy content of folder to multiple folders bash - bash

I want to copy the content of source folder to destination folders in one line, is that possible ?
I have this
cp -r source/* dest1 dest2 dest3
but it doesn't work, what it does it copies the 3 folders (source dest1 dest2) in dest3 and I want the content from source folder to each dest folder.

Do you mean you want to make three copies?
for dest in dest1 dest2 dest3 ; do
cp -r source/* "$dest"
done
Or, use xargs to avoid the loop:
echo dest1 dest2 dest3 | xargs -n1 cp -r source/*

Use a for:
for dest in dest1 dest2 dest3; do cp -r source/* "$dest"; done

Related

Is there a way to prepend file names based on respective folders?

I have a few folders with word document files of my notes. I want to run a simple bash loop help organise the names.
The current layout is:
data
folder1
1.jpg
2.jpg
folder2
1.jpg
.. etc
I want to rename all the jpg files so that it is folderX_1.jpg.
Can it be done only writing one loop?
Try this:
#!/bin/bash
origdir=$(pwd)
rm -fr source
mkdir source
cd source
mkdir folder1
touch folder1/1.jpg
touch folder1/2.jpg
mkdir folder2
touch folder2/1.jpg
cd ..
find source -type f -print0 | while IFS= read -r -d '' onefile
do
dirname=$(dirname "$onefile" | tr '/' '-')
filename=$(basename "$onefile")
cp "$onefile" "$origdir"/"$dirname"-"$filename"
done
The first part is just to create a test directory / file structure, remove or modify as required.
The find ... | while ... loops through each file in the directory / sub-directory structure.
for each file, extract the directory name (replacing '/' by '-' for sub-directories), extract the filename and copy the file.
if you want to move instead of copy, change cp by mv

How to remove empty directories from a tarball in-place

I extracted a layer from a docker image which archived in a file called layer.tar. I want to remove empty directories from it.
I don't want to unpack then repack files in that archive, I want to keep the original info, so I want to do it in-place.
I know how to delete files from tar but I don't know any simple method to delete empty directories in-place.
Let's create a archive t.tar with a/b/c/ and a/b/c/d/ empty directories:
mkdir -p dir
cd dir
mkdir -p a/b/c/d
mkdir -p 1/2/3/4
touch a/fil_ea a/b/file_ab # directory a/b/c and a/b/c/d are empty
touch 1/2/3/file_123 1/2/3/4/file_1234 # directories 1/2/3/4 not empty
tar cf ../t.tar a 1
cd ..
Using tar tf and some filtering we can extract the directories and files in a tar archive. Then for each directory in tmpdirs we can check if it has any files in tmpfiles with a simple grep and then remove those directories using --delete tar option:
tar tf t.tar | tee >(grep '/$' > tmpdirs) | grep -v '/$' > tmpfiles
cat tmpdirs | xargs -n1 -- sh -c 'grep -q "$1" tmpfiles || echo "$1"' -- \
| tac \
| xargs -- tar --delete -f t.tar
Not that tac is a bit unneeded, but the files where sorted alphabetically in tar, so when tar removes the directory a/b/c/ with all subdirectories first and then tries to remove a/b/c/d/ directory it fails with an Not found in archive in error. tac is a cheap way to fix that, so tar first removes a/b/c/d/ and then a/b/c/.

Copy files from list while keeping subdirectory structure

I have a text file which specifies files that need to be copied:
...
b/bamboo/forest/00000456.jpg
b/bamboo/forest/00000483.jpg
...
c/corridor/00000334.jpg
c/corridor/00000343.jpg
...
However, I would like to copy them while preserving their subdirectory structure. So the result would be:
...
newfolder/b/bamboo/forest/00000483.jpg
newfolder/b/bamboo/forest/00000456.jpg
...
newfolder/c/corridor/00000334.jpg
newfolder/c/corridor/00000343.jpg
...
I have this cat /path/to/files.txt | xargs cp -t /dest/path/. But it just copies everything to one directory.
You can use cp --parents:
--parents -- append source path to target directory
cat /path/to/files | xargs cp --parents -t new_directory
If that isn't working for you, then you can take the boring approach and iterate over each file in /path/to/files.txt and use mkdir -p to make target directories as needed, and then simply copy the file:
while read -r file; do
new_dir="new_directory/$(dirname "$file")"
# ^ this is the new directory root
mkdir -p "$new_dir"
cp "$file" "$new_dir/$file"
done < <(cat /path/to/files.txt)

How can I recursively copy same-named files from one directory structure to another in bash?

I have two directories, say dir1 and dir2, that have exactly the same directory structure. How do I recursively copy all the *.txt files from dir1 to dir2?
Example:
I want to copy from
dir1/subdir1/file.txt
dir1/subdir2/someFile.txt
dir1/.../..../anotherFile.txt
to
dir2/subdir1/file.txt
dir2/subdir2/someFile.txt
dir2/.../..../anotherFile.txt
The .../... in the last file example means this could be any sub-directory, which can have sub-directories itself.
Again I want to do this programmatically. Here's the pseudo-code
SRC=dir1
DST=dir2
for f in `find ./$SRC "*.txt"`; do
# $f should now be dir1/subdir1/file.txt
# I want to copy it to dir2/subdir1/file.txt
# the next line coveys the idea, but does not work
# I'm attempting to substitute "dir1" with "dir2" in $f,
# and store the new path in tmp.txt
echo `sed -i "s/$SRC/$DST/" $f` > tmp.txt
# Do the copy
cp -f $f `cat tmp.txt`
done
You can simply use rsync. This answer is based from this thread.
rsync -av --include='*.txt' --include='*/' --exclude='*' dir1/ dir2/
If you only have .txt files in dir1, this would work:
cp -R dir1/* dir2/
But if you have other file extensions, it will copy them too. In this case, this will work:
cd /path/to/dir1
cp --parents `find . -name '*.txt'` path/to/dir2/

How to copy in bash all directory and files recursive?

I have script:
find ./SourceFolder/ -maxdepth 4 -exec cp -R '{}' ./DestFolder/ \;
SourceDir contains also sub-folders.
Problem that in DestFolder not only all tree, but in up level all another levels and files.
How to fix ?
cp -r ./SourceFolder ./DestFolder
code for a simple copy.
cp -r ./SourceFolder ./DestFolder
code for a copy with success result
cp -rv ./SourceFolder ./DestFolder
code for Forcefully if source contains any readonly file it will also copy
cp -rf ./SourceFolder ./DestFolder
for details help
cp --help
also try this cp -r ./dist/* ./out;
this command will copy dist/* files to out dir;
You might find it handy to keep your attributes set
cp -arf ./SourceFolder ./DestFolder

Resources