How can I use two parameters at once with xargs?

The reason people use xargs in combination with find is that multiple file names will be passed to the same program invocation of whatever program xargs launches. For example, if find returns the files foo, bar, and baz, the following will run mv only once:

find sourceDir [...] -print0 | xargs -0 mv -t destDir

Effectively, it calls mv like the following:

mv -t destDir foo bar baz

If you don't need or want this behavior (as I assume is the case here), you can simply use find's -exec.


In this case, an easy solution would be to write a short shell script, like the following:

#!/usr/bin/env bash
[[ -f "$1" ]] || { echo "$1 not found" ; exit 1 ; }
P="$1"
F="$( basename $P )"
ffmpeg -i "$P" -f flv "$F"

Save as myffmpeg.sh and run chmod +x myffmpeg.sh. Then, run the following:

find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;

This will invoke the shell script once for every file found. The shell script in turn extracts the file name from the full path, and calls ffmpeg with the appropriate arguments.


I did not get the solution I was expected, so I found out my own. @Daniel's answer is good, but it need a shell script. A one liner is quicker, and I like it better :) also simpler solution than writing a script.

I could use one argument and process it with basename and using sh -c

find . -iname "*.mov" -print0 | xargs -0 -i sh -c 'ffmpeg -i {} -f flv `basename {}`'

The -i tells to xargs to replace {} with the current argument.
Command output inside `` printed out to standard output (bash feature) so basename {} will be evaluated as the bare file name and printed out.
-0 for handling special file names properly, but you need to pass parameters with the -print0 option with find


Something like this will do the trick and preserve full path, handle space, rename folder/movie.mov to folder/movie.flv, etc.

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done

And if I misunderstood you and you want all the .flv movies in the current directory, use this one instead:

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done