Command Line – How to Pass the Result of find as a List of Files

command lineshell

The situation is, I have an MP3 player mpg321 that accepts a list of files as argument. I keep my music in a directory named "music", in which there are a few more directories. I just want to play all of them, so I run the program with

mpg321 $(find /music -iname "*\.mp3")

. The problem is, some file names have whitespace in them, and the program breaks those names into smaller parts and complains about missing files. Wrapping the result of find in quotes

mpg321 "$(find /music -iname "*\.mp3")"

does not help because all will become one big "file name", which is obviously not found.

How can I do this then? If that matters, I am using bash, but will be switching to zsh soon.

Best Answer

Try using find's -print0 or -printf option in combination with xargs like this:

find /music -iname "*\.mp3" -print0 | xargs -0 mpg321

How this works is explained by find's manual page:

-print0

True; print the full file name on the standard output, followed by a null character (instead of the newline character that -print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.

Related Question