Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am trying to make a bash script that will find all the mp3s in my Downloads folder and move them into a music folder. Why won't this line work?

find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST

I tried using a pipeline to have the information from the first command translate to the second, but I have never used a pipeline before and don't know if I'm doing it wrong or if I have the wrong idea of what they are used for.

share|improve this question
add comment

2 Answers 2

up vote 5 down vote accepted

The mv command do not use its stdin, so you have to translate the stdin to a parameter, and for this can be used xargs:

find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST

Also, you can directly use the -exec action of find:

find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'

Edit

As pointed out by @geirha, the first command do not work if you have filenames containing spaces. In such a case it should be as follows

find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST
share|improve this answer
    
Hey thanks a lot. The first one didn't work for some reason, but the second one did. I'm just starting this stuff so I don't know what the parts you added means, but hopefully I can figure it out. –  LurkDog Mar 1 '12 at 6:57
1  
@LurkDog, the first one, with xargs, will fail if any of the filenames contain whitespace or quote characters, so that's probably why it failed for you. The second one, using find's -exec instead, is 100% safe in this regard. No matter what characters the filenames contain, it'll pass them on to mv intact. –  geirha Mar 1 '12 at 8:26
add comment

The advantage of xargs is that command line expansion. If you had a command that returned a very large amount of text (or many files all on one command) the you would need xargs.

If you had several thousand files in a directory and wanted to run some script on that list, you might try "./myprogram *", but if your program has any limits on the size of a parameter you might blow the buffer by expanding *. Also, the command line itself has limits so the command may fails because the command line buffer is overrun. The use of xargs will avoid the problem.

lastly, the -print0 on find will put null delimiters for spaces in the returned file names, and the -0 option on xargs will interpret those nulls. Read man xargs.

share|improve this answer
add comment

Your Answer

 
discard

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.