find: -exec vs xargs (aka Why does "find | xargs basename" break?)

Solution 1:

Because basename wants just one parameter... not LOTS of. And xargs creates a lot of parameters.

To solve your real problem (only list the filenames):

 find . -name '*.deb' -printf "%f\n"

Which prints just the 'basename' (man find):

 %f     File's name with any leading directories
        removed (only the last element).

Solution 2:

Try this:

find . -name '*.deb' | xargs -n1 basename

Solution 3:

basename only accepts a single argument. Using -exec works properly because each {} is replaced by the current filename being processed, and the command is run once per matched file, instead of trying to send all of the arguments to basename in one go.

Solution 4:

xargs can be forced to just pass one argument as well...

find . -name '*.deb' -print | xargs -n1 basename

This works, however the accepted answer is using find in a more appropriate way. I found this question searching for xargs basename problems as I'm using another command to get a list of file locations. The -n1 flag for xargs was the ultimate answer for me.