find — how to replicate a complex directory and file structure

Consider an example where you have a directory, called timit with many sub-directories that contain lots of files. Now, lets say you want to create a mirror copy of this complex directory structure in the /tmp directory, as well as a selective copy of its files based on certain pattern. Lets say we only want to copy files that have the following string somewhere in their filename, snr15. There are many possible solutions to this problem, you could write a perl or bash script, you could possibly use the rsync utility, but the simplest way I could find (on the Fedora Forum) is to use the Linux find command. Let me show you how it is done. It is a two step process. First step is to create a mirror copy of the directory structure as follows.

$ find timit/ -type d -exec mkdir -p /tmp/{} \;

# ©2007 linux.dsplabs.com.au

The second step is to create a copy of the files matching a specific criteria.

$ find timit/ -type f -name "*snr15*" -exec cp -p {} /tmp/{} \;

# ©2007 linux.dsplabs.com.au

If you wanted to conserve the disk space you could create hard links to the original files instead of actually copying them. This is especially useful if you are not going to modify any of the linked files (keep in mind that changes to linked files under /tmp/timit would also be reflected under ./timit and vice versa). Here is the modified command.

$ find timit/ -type f -name "*snr15*" -exec ln {} /tmp/{} \;

# ©2007 linux.dsplabs.com.au

If you prefer soft links instead of hard links, then replace the ln above with ln -s. OK, to finish up, let me mention a couple of other useful find one-liners. Either of the following commands could be used to remove all of the files containing a snr30 sub-string from the original directory.

$ find timit/ -type f -name "*snr30*" -delete $find timit/ -type f -name "*snr30*" -print0 |xargs -0 rm -f

On the other hand, to remove all of the files that did not contain the snr30 sub-string the following command could be used.

$ find timit/ -type f ! -name "*snr30*" -delete

Linux find command is a very versetile and useful tool, make good use of it!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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