Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a folder 'foo' that contains a lot of sub folders, e.g.


There are way more than this, but hopefully it explains the scenario. I now want to copy all folders from this folder that start '2011' into a sibling of 'foo' called 'bar'. However, 'bar' already contains some folders with the same name


The contents of the source and destination folder should be merged. Notice that the script will also need to create a bar/20112 folder as that doesn't exist.

I'm new to Mac Terminal scripting and have successfully managed to grep the right folders

foo>ls | grep ^2011 

Which lists the right folders, but I've no idea how to pipe that over to an appropriate copy operation.

share|improve this question
up vote 7 down vote accepted

The copy command is cp. If you give it the -r (recursive) flag, it will do exactly what you want, it will copy files into existing folders and create new folders when the destination folder is missing.

However, you should never parse the output of ls, you should use find or, even simpler, bash globbing:

cp -rv foo/2011* bar/

If there are files as well as folders whose name begins with 2011, use find and its -exec option which will apply whatever command you give it to everything found by find (referred to as {}):

find foo/ -type d -name "2011*" -exec cp -rv '{}' bar/ \;

In this specific case there is no reason to save the output of a command and pass it to cp. This is sometimes necessary though so here's how its done. In general, the output of a command can be given as input to another command if placed inside inverted comas or $().

cp -rv `find foo/ -type d -name "2011*"` bar/


cp -rv $(find foo/ -type d -name "2011*") bar/

Alternatively, you can loop through the results:

for dir in $(find foo/ -type d -name "2011*"); do cp -rv "$dir" bar/; done

This gets more complicated if your file/folder names can contain special characters or new lines and the like, in that case you should do something like this:

find foo/ -type d -name "2011*" | while IFS= read -r dir; do 
       cp -rv "$dir" bar/; 
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .