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