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.

  • was any of the answers useful? – Simply_Me Aug 11 '14 at 4:07
  • I have chosen the loop one. All were good for me but I can choose only one. Thanks – user67186 Aug 12 '14 at 18:26
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
  • 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 8 '14 at 20:47
  • 1
    @Simply_Me - Yes of course, but I was going for quick and dirty. – Jared Aug 8 '14 at 21:05
  • cool, just wanted to point out it can be shorter :-) – Simply_Me Aug 8 '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]

  • Wouldn't this copy server3 to itself as well? Could be time consuming if it's a large directory. – Simply_Me Aug 8 '14 at 21:17
  • no, the cp command will complain that it can't copy a directory on itself – pqnet Aug 8 '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 8 '14 at 21:26
  • For speed enhancement use specific wildcards (see edit) – Chemik Aug 8 '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 8 '14 at 21:32
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.

  • 1
    the ls solution will fail if ls decides to put more than one file for each row. Use ls -1 – pqnet Aug 8 '14 at 21:33
  • @pqnet thank you for the correction, I edited the answer. – Simply_Me Aug 8 '14 at 21:35
  • no, not -l which stands for 'long', you have to use -1 which stands for 'one' – pqnet Aug 8 '14 at 21:36
  • @pqnet sorry I thought that's 1.... – Simply_Me Aug 8 '14 at 21:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.