[X-Unix] copy 101 question

James Bucanek subscriber at gloaming.com
Sat Jun 5 15:14:06 PDT 2004


Scott Warren wrote on Saturday, June 5, 2004:

>I am wanting to back up just .doc files onto my firewire drive.  What 
>is the Mac/Unix version of
>   xcopy *.doc E:\backup -r
>
>I have tried  cp -R *.doc \volumes\myfirewire    and this only copies 
>whats in the current directory and does not recurs the tree.

Welcome to UNIX.

What you're trying to do it a little foreign to UNIX.  Unlike DOS, most UNIX program don't do their own globbing and recursion.  It's the job of the shell to expand '*.doc', and pass that as multiple arguments to the tool.  Consequently, you can't combine recursion with shell patterns.

But fear not:  I guarantee you that there's nothing you can do in DOS that you can't do in UNIX!

In UNIX, the Swiss Army knife of directory recursion is the Find tool.  Heres one way to use the find tool in combination with the tar (Tape ARchive) tool to transfer a sparse set of hierarchically organized files from one directory tree to another:

    cd ~
    find Documents -type f -name '*.doc' -print0 | tar -cf - --files-from - --null | tar -xvf - -C /Volumes/firewire

In English, I used the find tool to search my entire Documents folder for regular files (this excludes any directories or symbolic links) who's name matches the patter '*.doc'.  I piped this list to the tar tool and told it to create an archive (c) outputting the results to stdout (-f -).  Instead of listing the files to archive on the command, I told it to read the list of files from stdin (which will be the output of the find tool).  Finally, I piped the resulting archive directly into a second invocation of tar that extracts (-x) the archive read from stdin (-f -) into a specific directory (-C /Volumes/firewire).  The -v option just outputs the names of the files as they are processed so we can watch the fun.

The only other trick I used was to have find delimit the filenames with NULL characters instead of carriage returns, and I told tar to expect the filename list to be NULL terminated (--null) instead of a plain text list.  This combination makes it possible to safely process a list of filenames with all manor of special characters.  Remember that Mac filenames are Unicode, so they can contain any character in the world except slash (/) and NULL.

Having provided this example, I will now warn you that there are probably two dozen other ways of accomplishing the same thing.  Most probably much better than this example.  If you're doing this for backup purposes, I'd investigate the many synchronization programs that exist.  These will automatically mirror one directory tree to another, and do it incrementally so that it's fast and efficient.  Other tools will property preserve the Macintosh resource forks, which are extremely important to preserve for some file types.

If you're really interested in the OS X shell, there are tons of good books out there on using the UNIX shell, many written specifically for Macintosh users.  Check out the Mac OS X section of O'Reilly <http://mac.oreilly.com/>.

______________________________________________________
James Bucanek       <mailto:privatereply at gloaming.com>



More information about the X-Unix mailing list