Copying a single file to multiple directories using cp
Solution 1
If you wanted to use the output from your command to copy the file to each directory using cp
, you could always pipe it to xargs
:
printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt
There shouldn't be any concerns about the safety of parsing the output since you know its format and content before hand--the risk of encountering meta characters and space in file names isn't really an issue here.
Alternatively, assuming the directories already exist, you could try something like:
find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}
or with no pipe:
find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;
The last two commands will find any files in the current directory and cp
test.txt
to them. The -maxdepth 1
option will avoid any sub directories receiving the file as well. Be warned that 's[0-9][0-9]'
is matching against s
followed by any two digits, which means if for some reason you have s99
in the cwd
, it will also receive a copy of test.txt
.
Solution 2
You can also let the shell do the iterations with a for
loop. This is the most basic way that doesn't rely on external tools like parallel
or xargs
, and I find it easiest to understand:
for name in $(printf "s%02i " $(seq 1 50)); do
mkdir $name
cp test.txt $name
done
There are a million other ways to write this, e.g.:
for name in $(seq -w 1 50); do
mkdir s$name
cp test.txt s$name
done
If you want to verify what would be executed before doing it, you can do something like prepending the commands with echo
, which will print the line rather than executing it:
for name in $(seq -w 1 50); do
echo mkdir s$name
echo cp test.txt s$name
done
outputs:
mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.
Solution 3
According to this: https://stackoverflow.com/questions/195655/how-to-copy-a-file-to-multiple-directories-using-the-gnu-cp-command it is not possible to copy one file to multiple destinations. Check the link, as it shows another way to do this.
Solution 4
You could also use GNU parallel. Assuming your are in the directory containing text.txt and your 50 dirs are located in /my/50dirs/path
(like /my/50dirs/path/s01
, /my/50dirs/path/s02
etc) you would run:
seq -w 01 50 | parallel -j1 cp text.txt /my/50dirs/path/s{}
Related videos on Youtube
eikonal
Updated on September 18, 2022Comments
-
eikonal over 1 year
This question is a sequel of sorts to my earlier question, Creating numerous directories using
mkdir
.I am using the
bash
shell. I have created fifty directories, each starting with the prefix "s", using the command:mkdir $(printf "s%02i " $(seq 1 50))
which pads to the second digit with zeros. That is, the directories that I obtain are of the form
s01
,s02
, ...,s49
,s50
.Now I would like to use
cp
to copy a single file (for example,test.txt
) to each of the fifty directories. Is it possible to do this in a way analogous to that above? For example, would the following work? I am relatively new to Unix/Linux, so I don't really want to try this until someone please gives me an indication that it is safe.cp test.txt $(printf "s%02i.txt " $(seq 1 50))
Looking at the
man
page forcp
, it does not look likecp
supports multiple destinations like this, however:NAME cp - copy files and directories SYNOPSIS cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE... DESCRIPTION Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. Mandatory arguments to long options are mandatory for short options too.
-
Gilles 'SO- stop being evil' over 11 yearsBetter make that
parallel -j1
, otherwise there will be one job per core, and on a multicore machine the jobs will compete for IO. -
usretc about 3 years... unless the destinations are on different drives etc