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?
5 Answers 5
If you use bash in a recent version, you can profit from the globstar option:
shopt -s globstar
mv **/*.pdf papers/
-
1Bash versions greater than 4.0-alpha wiki.bash-hackers.org/internals/shell_options#globstarColonel Panic– Colonel Panic2012年09月20日 19:01:25 +00:00Commented Sep 20, 2012 at 19:01
find /bunchopdfs -name "*.pdf" -exec mv {} /papers \;
Here's a test I did
$ ls -R
.:
a aaa bbb.pdf pdfs
./a:
foo.pdf
./pdfs:
Notice the file "aaa bbb.pdf".
$ find . -name "*pdf" -exec mv {} pdfs \;
$ ls -R
.:
a pdfs
./a:
./pdfs:
aaa bbb.pdf foo.pdf
-
Beautiful! +1 !PenguinCoder– PenguinCoder2012年09月20日 15:44:18 +00:00Commented Sep 20, 2012 at 15:44
-
Don't you need to quote
"{}"to deal with file names containing spaces?terdon– terdon2012年09月21日 16:10:14 +00:00Commented Sep 21, 2012 at 16:10 -
@terdon: Actually, no you don't (though that sort of problem does catch me out sometimes). See updated answer.RedGrittyBrick– RedGrittyBrick2012年09月21日 16:22:50 +00:00Commented Sep 21, 2012 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.
-
1xargs has the issue of "spaces in filenames" that -exec doesn't. You can mediate this somewhat by adding args
-print0to your find, and-0to xargs.Rich Homolka– Rich Homolka2012年09月20日 20:00:05 +00:00Commented Sep 20, 2012 at 20:00 -
@RichHomolka see changed answer. (Thanks for the tip. That is really useful!)Trevor Boyd Smith– Trevor Boyd Smith2012年09月24日 10:32:20 +00:00Commented Sep 24, 2012 at 10:32
-
Have you ever tried that? Looks like you need to add the "-print0" at the end of the find commandtollo– tollo2018年05月16日 16:41:20 +00:00Commented May 16, 2018 at 16:41
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
-
1Hi and welcome to SU. Thank you for your answer, but the question specifically requests a linux solution.terdon– terdon2012年09月21日 16:05:23 +00:00Commented Sep 21, 2012 at 16:05
-
2It is still marvelous that windows can do that too!Vorac– Vorac2012年09月26日 10:01:38 +00:00Commented Sep 26, 2012 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.
a/x.pdfandb/x.pdf?