3

I have one parent directory /home/test and under that directory I have multiple directories. The names are server{1..10} and one of them server3 has few files which I have copied from remote server. I tried to use cp but it's not working for me. Is there a way to copy all files or one file from server3 directory to rest of the server directories under /home/test.

Braiam
  • 35,991
user67186
  • 497

3 Answers3

1

cp can handle multiple sources, but it can not handle multiple destinations.

You can use echo dir1 dir2 dir3 | xargs -n 1 cp file1 this will copy file1 to dir1, dir2 and dir3, for example.

Another modification is echo dir1 dir2 dir3 | xargs -n 1 cp /home/test/server3/* which will copy all of the files in a given directory to the echoed directories.

Additional solution, which is a bit shorter (w/o the need to enter directory names) is:

ls -1 | grep -v server3 | xargs -n 1 cp server3/*

Lastly, seems like a duplicate

Adding example for first solution:

# creating sample dir structure
[shadowe@shadow Desktop]$ mkdir server1
[shadowe@shadow Desktop]$ mkdir server2
[shadowe@shadow Desktop]$ mkdir server3
[shadowe@shadow Desktop]$ touch server3/test.one
[shadowe@shadow Desktop]$ touch server3/test.two
[shadowe@shadow Desktop]$ ls -R
./server1:
./server2:
./server3:
test.one  test.two

# executing solution
$ echo /home/shadowe/Desktop/server2/ /home/shadowe/Desktop/server1/ | xargs -n 1 cp /home/shadowe/Desktop/server3/*

# verifying solution
[shadowe@shadow Desktop]$ ls -R
./server1:
test.one  test.two
./server2:
test.one  test.two
./server3:
test.one  test.two

Adding example for second solution:

# showing directories structure and initial state
$ ls -R
server1:
server2:
server3:
test.one  test.two
server4:
server5:
server6:

# executing command
$ ls -1 | grep -v server3 | xargs -n 1 cp server3/*

# checking results
$ ls -R
./server1:
test.one  test.two
./server2:
test.one  test.two
./server3:
test.one  test.two
./server4:
test.one  test.two
./server5:
test.one  test.two
./server6:
test.one  test.two

As seen, both commands copied all of the files under server3 to other directories, so it's a matter of preference and use case.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
Simply_Me
  • 1,752
1

If I'm understanding what you're after, the easiest way is a for loop:

myList="server1 server2 server4 server5 server6 server7 server8 server9 server10"
for myDir in $myList ; do cp server3/* $myDir/ ; done
Jared
  • 126
  • 1
    It's possible to remove the list by using ls and grep in the for loop. For example for dirs in $( ls testing | grep -v 3 ); do echo $dirs; done results in server1 server2 server4 server5 server6 omitting server3 dir. – Simply_Me Aug 08 '14 at 20:47
  • 1
    @Simply_Me - Yes of course, but I was going for quick and dirty. – Jared Aug 08 '14 at 21:05
  • cool, just wanted to point out it can be shorter :-) – Simply_Me Aug 08 '14 at 21:19
1

The simplest way is to do this in one loop:

for i in ./server*; do cp ./server3/testfile* "${i}"; done

It will copy content of server3 directory to each directory in current path. This will also try to copy files to same directory but it only prints out that they are the same files and continues.

Edit: To avoid nasty error messages you can enhance for loop with more specific wildcard. For example to skip server3 use following: server[1-24-9]

Chemik
  • 214
  • Wouldn't this copy server3 to itself as well? Could be time consuming if it's a large directory. – Simply_Me Aug 08 '14 at 21:17
  • no, the cp command will complain that it can't copy a directory on itself – pqnet Aug 08 '14 at 21:22
  • @pqnet thanks, I tested it after commenting and it's exactly as you said. Still inefficient in large directories. – Simply_Me Aug 08 '14 at 21:26
  • For speed enhancement use specific wildcards (see edit) – Chemik Aug 08 '14 at 21:29
  • 1
    it won't improve speed, as cp will bail out without doing anything if the source path and the destination path are equal, but it does not print nasty error messages. It could fail if there are spaces in the name of the directory though, thus maybe it could be a good idea to put "$i" instead of ${i} – pqnet Aug 08 '14 at 21:32
  • Thanks, you are right. It is only one cp call less. – Chemik Aug 08 '14 at 21:42