Recursive wildcard copying?
This may seem like a stupid question... but I can't figure it out! In a shell, is there a way to recursively copy files of a certain type?
As an example, say you had multiple mp3's in different directories, mixed with other files and you wanted to copy only the mp3's to a single directory. I thought a command like: 'cp -R *.mp3 newdirectory' would work, but it doesn't. Is there a way to do this? The DOS equivalent would be 'xcopy *.mp3 c:\newdirectoy /S' Am I missing something or can this not be done? |
Read up on the find command: man find
This might be good enough, but you should really check the options available to make sure there isn't another combination thart would fit your needs: find -type f -name "*.mp3" -exec cp {} /destination \; Obviously, you need to replace /destination with the full path to the directory you want to put the mp3s in. |
since i wanted to answer that question so bad, i'll
elaborate a little. find starts in the current directory here, since it wasn't given a directory. you could give it one if you wished. like find /mp3 -type f -name "*.mp3" -exec cp {} /destination \; that would start in the directory mp3 if you wanted. -type f means type "file" (don't copy devices or links or directories. only files" that's probably not necessary. your choice. -name "*.mp3" thats kind of obvious, but will miss MP3 -exec executes the following line for each result find returns {} replaced with find result \; terminates -exec line my preference find . -name "[Mm][Pp]3" -print -exec cp {} /destination \: |
Thanks for the reply, looks like a long command - creating a script for this would be a good idea (unless this is already done?).
I thought this might be a very commonly asked question, suprised I couldn't find it easily through Google. Cheers. |
I thought this would be a nice "redeemer" for me... The last couple of posts on other threads were serious overkill for the task.
I'm more than willing to share the glory for helping on this thread though... :) Yeah, whansard is right about the -name portion, but he left out the wildcard and the dot for the extension. So, combining his and mine would give -name "*.[Mm][Pp]3" which is pretty much guaranteed to get all of them. I'm just a creature of habit. I add the -type f option as a safety net. Chances are it won't hurt anything, but yeah, you could probably get along without it. I don't think you need a script. It might be a long command, but it's still only one command. It'll be just as long in a script as it would be on the command line. --- Edit: You'll have to be careful with the script you've got. You can't use wildcards as your first argument without surrounding it in single quotes. If it's not in single quotes, the shell will expand it before executing your script; that would be a very bad thing for that script |
Yeah, but if its saved as a script it can be used again much quicker, with just a couple of arguments:
/bin/xcp-------------------------------------------- #!/bin/sh find -type f -name "$1" -exec cp -v {} /$2 \; ------------------------------------------------------- xcp *.mp3 newdirectory |
DOH! I wasn't fast enough with the edit...
See the edit on my previous post. An alias is typically used for single command expansion though, but there's nothing that says you can't use a script.. |
dangit! i'm mad i missed the *.
i was looking at the brackets too hard. you might want to use -ok instead of -exec if you're going to put it in a script or add a -i to the cp. i just love the find with the -exec switch and i wanted a piece of the action. i was testing the stuff i typed in first to make sure, but i didn't get it typed right in this box. in unix the long looking commands are the ones that do the cool stuff. i don't see as much use for the script cause i'm always having to type it with different commands. like bzip2 with txt files with rar for rar files with mv and cp find . -name "*.gz" -exec gzip -d {} \; find . -name "*.doc" -exec bzip2 {} \; find . -name "*.txt" -exec rm {} \; find . -name "*.wav" -exec lame . . . . something something |
All times are GMT -5. The time now is 02:08 PM. |