Here's one for all you command line gurus.

Live forum: /viewtopic.php?t=111


04-03-2005 20:05:41

How would you copy all of a certain file type throughout a directory and all it's subdirectories to a designated directory and using a single command line input.
There are several thousand *.txt files throughout a single computer.
How do you COPY all of the text files on this machine to one single location without going to each individual directory, copying, exiting, changing directories...blah blah blah.


04-03-2005 21:23:33

for i in `find / -iname *.txt`; do mv $i <newDir>/$i; done

That might work. I think you'll run into problems if you have files with the same names. Also if there are too many files you might need to use xargs.


05-03-2005 09:25:48

Um, don't do that, you need to replace "mv" to "cp" mv is very bad unless you know exactly what you are doing. You also might want to run the find part of that first to make sure it is going to behave like you expect. You might also want to pipe the output to a file using ">> filename.log" appended, so you will have a record of what you have done. ( or "> filename.log 2>&1")



05-03-2005 22:43:54

Good catch wolfie!


06-03-2005 08:34:32

:) I am just very paranoid of the mv, it can be a bad thing :)


06-03-2005 11:27:47

for i in `find / -iname *.txt`; do mv $i <newDir>/$i; done

My slight tweak would be:

find / -type f -iname "*.txt" -exec cp {} <newdir> \; &> cptxt.log

That takes the loop logic out of it and uses the exec command. Plus you know all your .txt files are going to be straight files, so you might as well specify that.

Edited to add:
Here's a quick way to figure out if you have more than one txt file with the same name in your directory structure:

find . -type f -iname "*.txt" -exec basename {} \; | wc -l
find . -type f -iname "*.txt" -exec basename {} \; | sort | uniq | wc -l

If those two commands don't return the same number, you have more than one .txt file with the same name.

A slight modification of the 2nd command above will tell you which files you have multiples of, and how many:

find . -type f -iname "*.txt" -exec basename {} \; | sort | uniq -c | sort -n -r