How to copy a file to multiple folders using the command line?

138,220

Solution 1

cp can copy from multiple sources, but can't copy to multiple destinations. See man cp for more info.

The only bash command that I know which can copy/save to multiple destinations is tee.

You can use it in your case as follows:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt

Note that tee also writes the input to the standard output (stdout). So if you don't want this, you can prevent it by redirecting standard output to /dev/null as follow:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null

Solution 2

Another way to achieve a copy to multiple locations is the following command :

find dir1 dir2 -exec cp file.txt {} \;

If dir1 or dir2 have sub-directories that you don't want the file copied into, add -maxdepth 0option :

find dir1 dir2 -maxdepth 0 -exec cp file.txt {} \;

Note that this will overwrite every file in dir1 and dir2 with file.txt's contents, in addition to copying it. To only copy file.txt without affecting other files in these directories, tell find to only act on directories:

find dir1 dir2 -type d -exec cp file.txt {} \;

Solution 3

The command

cp ~/test.txt ~/folder1 ~/folder2

tries to copy two files (~/test.txt and ~/folder1) to the destination folder2. (And if ~/folder2 exists and is a directory you will have an "omitting directory" warning).

If you want to make multiple copies of the file test.txt, you have to use a loop or multiple commands...

for i in ~/folder1 ~/folder2; do cp  ~/test.txt $i; done 

(...and be careful if you have spaces embedded in the file names, you'll need quoting).

To copy whole directories you have to use the -r option:

for i in ~/folder1 ~/folder2; do cp -r ~/folder3 $i; done

this will create ~/folder1/folder3 and ~/folder2/folder3 with all the files included.

Solution 4

You can create a help script , or you can do it with xargs and a print function (in this case, echo ):

echo firstDir secondDir | xargs -n 1 cp test

This will make each directory as an argument to the cp function , using test file as a parameter.

Solution 5

After a long search this work like a Charm also !

for dir in *; do [ -d "$dir" ] && cp /path/file.txt "$dir" ; done

This will copy file.txt to every directory in your current location in terminal.

for dir in *; do [ -d "$dir" ] && cp -rf /path/folder "$dir" ; done

This will copy a folder to every sub directory in your current location in terminal.

I share it hope it helps others too .

Share:
138,220

Related videos on Youtube

nux
Author by

nux

The Quieter you are , the more you are able to hear . "Once you stop learning, you start dying". -Albert Einstein Started learning Python . I am from Lebanon .

Updated on September 18, 2022

Comments

  • nux
    nux almost 2 years

    I have tried to copy a file test.txt to multiple directories with one command:

    cp ~/test.txt ~/folder1 ~/folder2
    

    But I didn't succeed. Is there a way to do that in one command so I can copy a file or even a folder to multiple directories?

    • Admin
      Admin over 10 years
      Not easily. You may want to look into "rsync" for efficiently updating multiple existing copies of a folder
    • Admin
      Admin over 10 years
      Try learning a bit of bash-script. It can get very useful: for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
    • Admin
      Admin over 7 years
      Not a single command but might just help some people who stumble upon here: cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
    • Admin
      Admin almost 7 years
    • Admin
      Admin over 4 years
      @ManuJärvinen comment may look flippant but it raises an important point. Why complicate your script? Two separate lines with a single copy is much more readable than all the other answers. I have not used tee much so if I saw the accepted answer in a script, I would have no idea what it was doing. I accept the answers are inventive but in a real world scenario you need simple.
  • terdon
    terdon over 10 years
    Clever, that's cheating! :)
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @terdon Only if you consider that I/O redirection is an independent command :)
  • Rmano
    Rmano over 10 years
    +1, clever! And if you use the >/dev/null works with binary files too, without messing up the terminal...
  • Danatela
    Danatela over 10 years
    Nice solution! Seems to me more perfect than with tee.
  • Sylvain Pineau
    Sylvain Pineau over 10 years
    Indeed, no redirection is involved and it's still one command.
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @SylvainPineau In fact there are 3: one is find and for two times (in this case) cp. Not to say that find need a lot of time.
  • nux
    nux over 10 years
    +1 for you , your always ma man :) , but what if i want to copy a directory ?
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @nux Your question was about a file. The other answers which uses cp in combination with other commands are good in case if you want to copy a directory.
  • nux
    nux over 10 years
    i will try answers and will report you the result , thanks man
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @nux Don't forget to use -r option with cp in case of directories
  • kojiro
    kojiro over 10 years
    If the definition of a "command" is an "exec" call, maybe, but this is "one command" in my book.
  • kojiro
    kojiro over 10 years
    For the passing reader: According to the spec, a for loop is a compound command. Therefore this is still one command, and meets all the requirements for the question.
  • Rmano
    Rmano over 10 years
    In zsh, you can use for i in *(/); ... to loop over all the subdirectories, so you can avoid the [ -d ... test. Extended globbing is one of the reason I like it over bash.
  • nux
    nux over 10 years
    can your right the code again in a command
  • Rmano
    Rmano over 10 years
    In zsh, the first command of this answer can be simplified as for dir in *(/); do cp /path/file.txt "$dir"; done. See zsh.sourceforge.net/Intro/intro_2.html
  • Michael Martinez
    Michael Martinez over 10 years
    technically two commands (find and cp) but no pipes so "looks" like one command ;-)
  • Henk Langeveld
    Henk Langeveld over 10 years
    @SylvainPineau This will also create one copy of the file for every subdirectory in dir1 and dir2.
  • Henk Langeveld
    Henk Langeveld over 10 years
    You can eliminate the test in any Bourne derived shell with for dir in */;
  • Sylvain Pineau
    Sylvain Pineau over 10 years
    @Henk, if dir1 or dir2 have subdirectory, adding -maxdepth 0 to the find command will prevent this behaviour.
  • Henk Langeveld
    Henk Langeveld over 10 years
    Correct. I already edited your answer. Enjoy!
  • jfs
    jfs over 10 years
    @nux: tee unlike cp copies only file's content ignoring its mode, ownership, timestamps. To avoid repeating the filename: f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
  • Rmano
    Rmano over 10 years
    @nux, I do not agree on the corrections. 1) the two capitals are wrong, my intent was to interleave the commands into the phrase. 2) the ellipsis is a matter of style; please let my style in.
  • nux
    nux over 10 years
    ok , am sorry man , i thought it will look better .
  • Jonathan
    Jonathan over 8 years
    I keep coming back to this one, so thought I should give an upvote :D
  • nukeguy
    nukeguy almost 8 years
    @nux This works really well and the command is very easy to follow. It should be voted much higher!
  • Elder Geek
    Elder Geek over 7 years
    I love tee almost as much as coffee! ;-)
  • alpha_989
    alpha_989 almost 7 years
    on my system, it doesnt save folder3 as ~/folder1/folder3, but rather copies everything in folder3 into folder1
  • Dennis Williamson
    Dennis Williamson over 6 years
    A way to avoid repeating the filename and the common part of the directory names, too!: f=text.txt; tee ~/folder{1..2}/$f < ~/$f > /dev/null
  • Bryson S.
    Bryson S. about 6 years
    This is probably the best/most direct answer to the question
  • jedmao
    jedmao about 4 years
    i just ran tee packages/*/.npmrc < .npmrc in a monorepo. you saved my life!
  • Timo
    Timo almost 4 years
    in zsh it truncated all files with tee.
  • Zanna
    Zanna over 2 years
    cp has a --verbose or -v flag which I find useful for scripts. One can also do a dry run with echo before the command ( do echo cp ...) and then remove the echo if the list is as expected, though running without sudo is also a convenient test for this particular scenario.