Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a folder structure with a bunch of *.csv files scattered across the folders. Now I want to copy all *.csv files to another destination keeping the folder structure.

It works by doing:

cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target

and so on, but I would like to do it using one command.

share|improve this question

migrated from serverfault.com Jul 19 '13 at 2:46

This question came from our site for system and network administrators.

5 Answers 5

Is there any reason why people resist using find's -exec? It's very handy.

find . -name '*.csv' -exec cp --parents \{\} /target \;

Know your tools. ;-)

share|improve this answer
Probably because of this \{\} \; –  igo Mar 4 at 13:56

You could also use rsync for this.

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/

If you want to keep empty directories from the source tree, skip the --prune-empty-dirs option:

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/

If you do not want symlinks, modification dates, file permissions, owners etc. preserved, please replace -a with another combination of -rlptgoD. ;-)

share|improve this answer

Assuming you want to replicate this structure from ./source to ./destination:

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)

I'm prepared to count that as one line, the cd source being a shell builtin.

share|improve this answer
I don't think he really means one command - just not having to fag about like his example ;) –  Iain Jul 18 '13 at 15:04

cp allows multiple source arguments:

cp **/*.csv --parent ../target

(Note that I'm using a recursive glob here; if you don't have that feature in your shell, use *.csv */*.csv */*/*.csv */*/*/*.csv or $(find . -name '*.csv').)

EDIT: Fixed find command. Haven't used it in a while and I hate that tool, so of course I messed it up on the first try...

share|improve this answer

You can use find and cpio in pass through mode

find . -name '*.csv' | cpio -pdm  /target

This will find all .csv files in the current directory and below and copy them to /target maintaining the directory structure rooted in ..

If you use

find /path/to/files -name '*.csv' | cpio -pdm /target

it will find all of the file in /path/to/files and below and copy them to /target/path/to/files and below.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.