Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm not very familiar with all the tricks of grep/find/awk/xargs quite yet.

I have some files matching a particular pattern, say *.xxx. These files are in random places throughout a certain directory. How can I find all such files, and move them to a folder in my home directory on Unix (that may not exist yet)?

share|improve this question
You've got to take care when talking about "file type". In unixy environments, the ".xxx" example isn't even an extension in the Windows sense. ".xxx" just constitutes a suffix of the file name. "File type" is more one of a few categories: regular file, device file, symbolic link, directory, named pipe, Unix-family socket, maybe a few others. – Bruce Ediger Feb 2 '12 at 22:13
See also: unix.stackexchange.com/questions/7027/… – jasonwryan Feb 2 '12 at 22:16
@BruceEdiger thanks I guess I really meant "filename pattern" – qodeninja Feb 3 '12 at 1:14
@jasonwryan thanks! – qodeninja Feb 3 '12 at 1:14
up vote 11 down vote accepted
mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;
share|improve this answer
I would use mv -i -t ~/dst {} + – enzotib Feb 3 '12 at 6:56

If you want to move all the files inside a directory hierarchy to a single destination directory, in bash ≥4 (put shopt -s globstar in your ~/.bashrc) or zsh:

mkdir ~/new-directory
mv -i **/*.xxx ~/new-directory

In other shells:

mkdir ~/new-directory
find . -name '*.xxx' -exec mv -i {} ~/new-directory \;

How to read this find command:

  • .: traverse the current directory
  • -name '*.xxx': act on files whose name matches this pattern
  • -exec … \;: perform this command on each file, replacing {} by the path to the file

There's a more complex command using find that's faster if you have many files as it doesn't need to invoke a separate mv process for each file:

find . -name '*.xxx' -exec sh -c 'mv -i "$@" "$0"' ~/new-directory {} +

The + at the end tells find to invoke the command on multiple files at a time. Since find can only put the file names at the end of the command line, and mv needs to have the destination directory last, we use an intermediate shell to rearrange the arguments ("$0" is the first argument to the shell, ~/new-directory, and "$@" are the subsequent arguments coming from find's expansion of {}).

share|improve this answer

If you want to replicate the directory structure of the matching source files to the new target directory, you can make use of GNU cp's --parents option:

mkdir /path/to/target_dir
cd source_dir
find . -name '*.xxx' -exec cp -iv --parents -t /path/to/target_dir {} +
share|improve this answer

you can use find without ‍‍-exec‍ as well:

mkdir /path/to/dest    
cp `find /path/to/source -name "*.jar"` /path/to/dest
share|improve this answer
Note however that find -exec is much safer; the above will fail on file names containing white space, for example. – dhag Apr 16 '15 at 14:30

Your Answer


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

Not the answer you're looking for? Browse other questions tagged or ask your own question.