Tuesday, 25 June 2013

Copy files in a directory tree matching pattern(s) while preserving the relative path

Have you ever wanted to copy all files of a certain type from a large directory tree to an identical directory tree?

For example, one time I needed to copy all the .so files from /var/lib/gems to the vendor directory because for some reason, dependencies didn't. Copying all files didn't appeal to me, so I made this script.

Example (greyed out directory entries for easier viewing):
$ du -a /source/path
0    /source/path/something.else
0    /source/path/dir/another/directory/or/two/3.txt
4    /source/path/dir/another/directory/or/two
8    /source/path/dir/another/directory/or
12   /source/path/dir/another/directory
16   /source/path/dir/another

0    /source/path/dir/2.txt
20   /source/path/dir
0    /source/path/directory/containing/no/txt/files/not_a_txt_file
4    /source/path/directory/containing/no/txt/files
8    /source/path/directory/containing/no/txt
12   /source/path/directory/containing/no
16   /source/path/directory/containing
20   /source/path/directory

0    /source/path/1.txt
44   /source/path
$ copy-files-matching-pattern-preserving-path /source/path "*.txt" /destination/path Copying *.txt from /source/path to /destination/path...
/source/path/dir/another/directory/or/two/3.txt ==> /destination/path/dir/another/directory/or/two/3.txt
/source/path/dir/2.txt ==> /destination/path/dir/2.txt
/source/path/1.txt ==> /destination/path/1.txt
$ du -a /destination/path
0    /destination/path/dir/another/directory/or/two/3.txt
4    /destination/path/dir/another/directory/or/two
8    /destination/path/dir/another/directory/or
12   /destination/path/dir/another/directory
16   /destination/path/dir/another

0    /destination/path/dir/2.txt
20   /destination/path/dir
0    /destination/path/1.txt
24   /destination/path


It's basically a bash script for copying all files in a directory tree matching one or more specified patterns (such as *.txt) to another tree, creating any directories not already existing. It copies only the path below the source directory to the destination, and only creates directories with files matching the pattern.

3 comments:

  1. http://superuser.com/questions/299938/how-can-i-recursively-copy-files-by-file-extension-preserving-directory-structu

    ReplyDelete
  2. short version:

    cd /top/level/to/copy
    find . -name '*.txt' | cpio -pdm /path/to/destdir

    ReplyDelete
  3. Well, you can use Long Path Tool for such problems....

    ReplyDelete