You can use -exec as your -test.
Write a script that takes one filename argument
and exits 0 if the file meets your condition and non-zero otherwise.
I don’t have the FF software (e.g., ffprobe) software on my system,
so I can’t check this, but something like
#!/bin/sh
if dur=$(ffprobe -i "$1" -show_entries format=duration -v quiet -of csv="p=0")
then
[ "$dur" -ge 900 ]
exit
else
exit
fi
would check for a video having duration ≥ 15 minutes,
assuming ffprobe outputs an integer number of seconds.
(If it reports mm:ss or ss.ddd, I leave the trivial modifications to you,
but see my example below for inspiration.)
Explanation: the if fails if ffprobe fails;
in that case, we drop to the lower exit
and exit with the error status from ffprobe.
If ffprobe succeeds, we test its output ("$dur")
and then exit with the result of that test.
This could also be written
[ "$dur" -ge 900 ] && exit 0 || exit 1
In fact, the entire script can really be reduced to
dur=$(ffprobe -i "$1" -show_entries format=duration -v quiet -of csv="p=0") \
&& [ "$dur" -ge 900 ]
So call your script something like check_dur; then you can do
find . -exec ./check_dur {} ';'-exec mv {} /path/to/target ';'
This works because, as I said, -exec functions as a test,
and things after a -exec will be processed
only if the first -exec succeeded (exited with status 0).
As I said,
I don’t have the FF software (e.g., ffprobe) software on my system,
so I tested with this script:
#!/bin/sh
if mod=$(stat -c%y "$1")
then
mod=${mod#*-}
mod=${mod%%-*}
mod=${mod#0}
[ $(( mod%2 )) = 0 ]
exit
else
exit
fi
which tests whether the modification date of a file or directory
is in an even-numbered month.
Note: on my (en_US) system, stat -c%y filename
outputs the modification date
in the format yyyy-mm-dd HH:MM:SS.ddddddddd -(TZ).
So the above code
- strips off the year (from the left),
- strips off everything after the month, and
- strips off a leading
0, if any
(because $((…)) interprets a leading zero
as an indicator that a number is octal,
and so it reports an error for 08 and 09).
A couple of other notes:
For mv, the command can be improved a little by changing it to
find . -exec ./check_dur {} ';' -exec mv -t /path/to/target {} +
which will execute mv once with many files.
You cannot do this with the first -exec,
because -exec ... + cannot be used as a test.
2. If you don’t want to write a separate script,
you can use sh -c and inline the script; e.g.,
find . -exec sh -c 'dur=$(ffprobe -i "$1" -show_entries format=duration -v quiet -of csv="p=0") && [ "$dur" -ge 900 ]' sh {} ';'-exec mv -t /path/to/target {} +
This creates a one-line mini-script (the string after the sh -c)
and passes the filename ({}) to it as an argument.
Some versions of find
will let you incorporate the {} into the mini-script,
but this is a bad idea:
- It doesn’t work for all versions of
find, and
- even when it works, in general,
it will fail (and maybe even fail catastrophically) for some filenames.