Question

Unix shell file copy flattening folder structure

On the UNIX bash shell (specifically Mac OS X Leopard) what would be the simplest way to copy every file having a specific extension from a folder hierarchy (including subdirectories) to the same destination folder (without subfolders)?

Obviously there is the problem of having duplicates in the source hierarchy. I wouldn't mind if they are overwritten.

Example: I need to copy every .txt file in the following hierarchy

/foo/a.txt
/foo/x.jpg
/foo/bar/a.txt
/foo/bar/c.jpg
/foo/bar/b.txt

To a folder named 'dest' and get:

/dest/a.txt
/dest/b.txt
 45  24970  45
1 Jan 1970

Solution

 63

In bash:

find /foo -iname '*.txt' -exec cp \{\} /dest/ \;

find will find all the files under the path /foo matching the wildcard *.txt, case insensitively (That's what -iname means). For each file, find will execute cp {} /dest/, with the found file in place of {}.

2008-08-26

Solution

 14

The only problem with Magnus' solution is that it forks off a new "cp" process for every file, which is not terribly efficient especially if there is a large number of files.

On Linux (or other systems with GNU coreutils) you can do:

find . -name "*.xml" -print0 | xargs -0 echo cp -t a

(The -0 allows it to work when your filenames have weird characters -- like spaces -- in them.)

Unfortunately I think Macs come with BSD-style tools. Anyone know a "standard" equivalent to the "-t" switch?

2008-08-26