Reputation: 2583
I'm trying to copy 4 files that are present in Folder A (main folder) into all subfolders (1000) present in Folder A. To do this I used:
for i in *;
do
cp File1.bash $i
cp File2.sh $i
cp File3.R $i
cp File4.R $i
done
Unfortunately, the content of all the files after the cp is overwritten in destination directories. In other words files: File2.sh, File3.R and File4.R have the content of File1.bash.
Can anyone help me to solve this problem?
Thank you very much
Upvotes: 1
Views: 123
Reputation: 1545
The for cycle goes through all files and directories (except ones which name starts with a dot) in the current directory including the files File1.bash
, File2.s
, File3.R
, File4.R
so sooner or later they will appear in the destination of the cp
commands and get overwritten.
There are multiple ways how to resolve the problem:
for i in */ ; do
cp File1.bash File2.sh File3.R File4.R "$i"
done
for i in * ; do
if test -d "$i" ; then
cp File1.bash File2.sh File3.R File4.R "$i"
fi
done
Compared to the first answer this code does not need to call an additional external command (ls
) and it is not a good idea to parse output of ls
anyway :) (It could contain some unexpected content.)
For example move the files to directory called .template
(the dot is important) or to a directory outside the current directory (../template
):
mv File1.bash File2.sh File3.R File4.R .template
Changed script (will not cycle through the hidden .template
):
source=.template
for i in * ; do
cp "$source/File1.bash" "$i"
cp "$source/File2.sh" "$i"
cp "$source/File3.R" "$i"
cp "$source/File4.R" "$i"
done
It is a good idea to enclose string where you expand variables between double quotes. Then the script will correctly work with string containing spaces newlines etc. too.
Upvotes: 1
Reputation: 1072
The problem here is that the wildcard *
is replaced by every file in the directory, including File2.sh,, File3.R and so on. So, at one point during the loop, $i will be 'File2.sh,' and you will execute the command cp File1.bash File2.sh
, which will overwrite File2.sh (the same problem happens for the other files).
You should replace the wildcard with a command which only list directory such as ls -d */
.
For instance :
for i in $(ls -d */)
do
cp File1.bash $i
cp File2.sh $i
cp File3.R $i
cp File4.R $i
done
Also , note that cp can take multiple arguments as source, so cp File1.bash File2.sh File3.R File4.R $i
should do what you want. It is also less error prone as the last parameter is expected to be a directory, so cp will give an error if $i is a regular file.
Upvotes: 1