Super User is a question and answer site for computer enthusiasts and power users. 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 have a directory containing a large number of PDF files, some of which are in subdirectories (which can extend several layers deep). I would like to move all files matching *.pdf into a single output folder named papers.

How can I do this?

share|improve this question
How would you like to handle the case there are two files a/x.pdf and b/x.pdf? – Colonel Panic Sep 20 '12 at 19:00
up vote 14 down vote accepted

If you use bash in a recent version, you can profit from the globstar option:

shopt -s globstar
mv **/*.pdf papers/
share|improve this answer
Bash versions greater than 4.0-alpha – Colonel Panic Sep 20 '12 at 19:01
  find /bunchopdfs -name "*.pdf" -exec mv {} /papers \;    

Here's a test I did

$ ls -R
a  aaa bbb.pdf  pdfs



Notice the file "aaa bbb.pdf".

$ find . -name "*pdf" -exec mv {} pdfs \;
$ ls -R
a  pdfs


aaa bbb.pdf  foo.pdf
share|improve this answer
+1 Native... global... – Mechaflash Sep 20 '12 at 15:28
Beautiful! +1 ! – PenguinCoder Sep 20 '12 at 15:44
Don't you need to quote "{}" to deal with file names containing spaces? – terdon Sep 21 '12 at 16:10
@terdon: Actually, no you don't (though that sort of problem does catch me out sometimes). See updated answer. – RedGrittyBrick Sep 21 '12 at 16:22
find -print0 /directory/with/pdfs -iname "*.pdf" | xargs -0 mv -t /papers

(similar to another answer but I prefer pipe/xargs/mv ... more intuitive for me)

FYI, I did the above one-line script successfully on multiple directories and multiple pdf files.

share|improve this answer
xargs has the issue of "spaces in filenames" that -exec doesn't. You can mediate this somewhat by adding args -print0 to your find, and -0 to xargs. – Rich Homolka Sep 20 '12 at 20:00
@RichHomolka see changed answer. (Thanks for the tip. That is really useful!) – Trevor Boyd Smith Sep 24 '12 at 10:32

For the Windows command line (cmd.exe), you can use:

for /F "usebackq delims==" %j IN (`dir /s /b *.pdf`) do copy "%j" c:\target_dir
share|improve this answer
Hi and welcome to SU. Thank you for your answer, but the question specifically requests a linux solution. – terdon Sep 21 '12 at 16:05
It is still marvelous that windows can do that too! – Vorac Sep 26 '12 at 10:01

If you're only searching one directory deep, you could do:

mkdir <destination>
mv */*.pdf <destination>

where <destination> stands for some directory. mv will not automatically create a directory for you.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .