Copying a single file to multiple directories using cp

12,159

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{}
Share:
12,159

Related videos on Youtube

eikonal
Author by

eikonal

Updated on September 18, 2022

Comments

  • eikonal
    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 for cp, it does not look like cp 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'
    Gilles 'SO- stop being evil' over 11 years
    Better make that parallel -j1, otherwise there will be one job per core, and on a multicore machine the jobs will compete for IO.
  • usretc
    usretc about 3 years
    ... unless the destinations are on different drives etc