Você pode usar -exec
como seu -test
.
Escreva um script que aceite um argumento de nome de arquivo
e sai 0 se o arquivo atender à sua condição e, caso contrário, não é zero.
Eu não tenho o software FF (por exemplo, ffprobe
) no meu sistema,
então eu não posso verificar isso, mas algo como
#!/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
procuraria por um vídeo com duração ≥ 15 minutos,
supondo que ffprobe
produza um número inteiro de segundos.
(Se relatar mm: ss ou ss.ddd, deixo as modificações triviais para você,
mas veja meu exemplo abaixo para inspiração.)
Explicação: o if
falha se ffprobe
falhar;
Nesse caso, baixamos para o menor exit
e saia com o status de erro de ffprobe
.
Se ffprobe
for bem-sucedido, testamos sua saída ( "$dur"
)
e saia com o resultado desse teste.
Isso também poderia ser escrito
[ "$dur" -ge 900 ] && exit 0 || exit 1
Na verdade, o script inteiro pode ser reduzido a
dur=$(ffprobe -i "$1" -show_entries format=duration -v quiet -of csv="p=0") \
&& [ "$dur" -ge 900 ]
Portanto, chame seu script de algo como check_dur
; então você pode fazer
find . -exec ./check_dur {} ';'-exec mv {} /path/to/target ';'
Isso funciona porque, como eu disse, -exec
funciona como um teste,
e as coisas depois de um -exec
serão processadas
somente se o primeiro -exec
for bem-sucedido (encerrado com status 0).
Como eu disse
Eu não tenho o software FF (por exemplo, ffprobe
) no meu sistema,
então testei com esse script:
#!/bin/sh
if mod=$(stat -c%y "$1")
then
mod=${mod#*-}
mod=${mod%%-*}
mod=${mod#0}
[ $(( mod%2 )) = 0 ]
exit
else
exit
fi
que testa se a data de modificação de um arquivo ou diretório
está em um mês com numeração par.
Nota: no meu sistema (en_US), stat -c%y filename
produz a data de modificação
no formato yyyy-mm-dd HH:MM:SS.ddddddddd -(TZ)
.
Então, o código acima
- retira o ano (da esquerda),
- retira tudo depois do mês e
- retira um
0
, se houver (porque$((…))
interpreta um zero à esquerda como um indicador de que um número é octal, e, portanto, relata um erro para08
e09
).
Algumas outras notas:
-
Para
mv
, o comando pode ser melhorado um pouco alterando-o parafind . -exec ./check_dur {} ';' -exec mv -t /path/to/target {} +
que executará
mv
uma vez com muitos arquivos. Você não pode fazer isso com o primeiro-exec
, porque-exec ... +
não pode ser usado como um teste. -
Se você não quiser escrever um script separado, você pode usar
sh -c
e inline o script; por exemplo,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 {} +
Isso cria um mini-script de uma linha (a string após o
sh -c
) e passa o nome do arquivo ({}
) para ele como um argumento. Algumas versões dofind
vai deixar você incorporar o{}
no mini-script, mas esta é uma má ideia:- Não funciona para todas as versões de
find
e - mesmo quando funciona, em geral ele falhará (e talvez até falhe catastroficamente) em alguns nomes de arquivos.
- Não funciona para todas as versões de