How to copy a file or a directory to multiple directories without a script in bash

Problem description

First of all I want to explictly explain my problem. Some times I have to copy a file or a directory to multiple locations in Unix Systems. I am bored to do a lot of copies and I am also bored to write a looped script for such a trivial thing. If your problem has a pattern (most common problems have a pattern), then all you need is to think as rationally as possible. So this can be assumed to be a How to copy a file or a directory to multiple directories without a script in bash tutorial.

Creating a list of directories where we want to make the copy

I will give an example to make it more clear. Let’s say we have a /var/www/sites*/public_html/ directory tree, where sites* could be all possible domain name’s our server hosts. Now we need to add an .htaccess file in each site’s public_html directory.

First of all you need somehow a list of all directories of /var/www/ directory. Everyone can do it.
ls -lah /var/www/

ok but you have both ../ and ./

just try

ls -ld /var/www/*/

now let’s say that the directories are named according to their domain tld (top-level domain) for example for the webplay.pro domain there is a webplay.pro directory and for the strimpak.com domain there is a strimpak.com directory and you want to copy the .htaccess not to all directories but to the .com domain corresponding directories. You can use grep to do this:

ls -ld /var/www/*/ | grep “.com”

Now it’s time to use awk tool! By using awk you can do a lot of cool things. One of this is that you can split your input to fields separetaed by tab (\t).

Just try this:

ls -ld /var/www/*/ | grep “.com” | awk ‘{print $9}’

and the result is to get a list of full paths which you want to use for a copy command. But you want to copy a file to /var/www/strimpak.com/public_html/ directory and not to
/var/www/strimpak.com/ so all you have to do is to use more the awk tool as below:

ls -ld /var/www/*/ | grep gr | awk ‘{print $9 “public_html/”}’

Using the list to execute commands

And now we have created a list of all directories where we want to copy a file or a directory or do whatever we want in a single line! Now we will use the xargs tool to pass the list we created to another command:

ls -ld /var/www/*/ | grep gr | awk ‘{print $9 “public_html/”}’ | xargs -n 1 echo “copy in here”

In the above example we passed the list to the echo command, just for testing purposes. We used the | (pipe) and passed the list to the xargs, with the ” -n 1″ switches we tell the xargs to use one argument at most per command.

Being safe

I ‘ll get a little bit out of topic but it’s crusial to make a refference to. The command we choosed to use is echo and not cp because you cannot do anything irreversible with echo. By copying file we may do something we would like to undo. Linux (like other unices) doesn’t natively provide an undo feature. The philosophy is that if it’s gone, it’s gone. If it was important, it should have been backed up.

Another way to protect against such accidents is to use a version control system (git, mercurial, subversion, …). It takes a little time to learn, but it pays off awesomely in the medium and long term.

Back to our main topic, we need to copy the file: /var/www/.htaccess to the directories selected:

ls -ld /var/www/*/ | grep gr | awk ‘{print $9 “public_html/”}’ | xargs -n 1 echo cp /var/www/.htaccess

and the job got done!!!

I hope you found how to copy a file or a directory to multiple folders in linux article useful. Whatever is told in this article can be used with your own risk.

Leave a Reply

Your email address will not be published. Required fields are marked *

Prove me that you are not a robot :) * Time limit is exhausted. Please reload the CAPTCHA.