Выполнить команду в bash, записать в переменную
time = exec "ffprobe -i /video.mp4 -show_entries format=duration -v quiet -of csv='p=0'"
echo ${time}
Данная команда возвращает продолжительность видео. Вопрос в том. Как выполнить команду и записать возвращаемое ею значение в переменную?
ffmpeg -i /video.mp4 -vf cropdetect -f null - 2>&1 | awk '/crop/ { print \$NF }' | tail -1
Так получаю
crop=*:*:*:*
Вопрос в том, возможно вместе кропом, получить значение продолжительности. И разбить кроп и время в 2 переменные, отдельно?
Ответы (1 шт):
Как выполнить команду и записать возвращаемое ею значение в переменную?
Чтобы сохранить данные, которые программа передает на стандартное устройство вывода, мы используем либо x=$(command ...)
либо x=`command ...`
(обрамляем команду обратными апострофами). Вокруг знака равенства не должно быть пробелов, иначе это будет интерпретировано как попытка запустить программу, а не присвоить значение переменной.
Как из cropdetect извлечь продолжительность и кроп в переменные?
Вы пытаетесь извлечь время и кроп из результата работы команды:
ffmpeg -i video.mp4 -vf cropdetect -f null - 2>&1
Для этого используете строку обработки последнего фрейма, которая выглядит так:
[Parsed_cropdetect_0 @ 0x55737988da80] x1:0 x2:1919 y1:0 y2:1079 w:1920 h:1072 x:0 y:4 pts:7908 t:0.514844 crop=1920:1072:0:4
Время и кроп расположены в конце строки в виде t:0.514844 crop=1920:1072:0:4
. Следовательно в awk
мы печатаем не одно, а два последних поля: awk '/crop/ {print $(NF-1), $NF}'
. Или не выводим, а сохраняем в две переменные, которые печатаем в конце:
awk '/crop=/ {time=$(NF-1); crop=$NF}
END {print substr(time, 3), substr(crop, 6)}'
Здесь substr(x, n)
- это часть строки x
начиная с позиции n
(нумерация начинается с единицы). То есть, команда может выглядеть так:
data=$(ffmpeg -i video.mp4 -vf cropdetect -f null - 2>&1 |
awk '/crop=/ {time=$(NF-1); crop=$NF}
END {print substr(time, 3), substr(crop, 6)}')
time=$(echo $data | cut -d' ' -f1)
crop=$(echo $data | cut -d' ' -f2)
В последних двух строках мы делим data
по пробелу и присваиваем левое/правое поле соответственно переменным time
и crop
. Впрочем, раз уж мы работаем в bash
и у нас всего 2 поля, то можем сделать это отрезая суффикс и префикс по пробелу:
time=${data% *}
crop=${data#* }
Более того, мы могли бы объявить data
ассоциативным списком и передать данные в таком формате, который можно использовать при его определении. Это может выглядеть так:
eval declare -A data=(`ffmpeg -i video.mp4 -vf cropdetect -f null - 2>&1 |
awk '/crop=/ {time=$(NF-1); crop=$NF}
END {print "[time]=" substr(time, 3),
"[crop]=" substr(crop, 6)}'`)
Посмотреть содержимое можно командой declare -p data
. Извлечь значения: ${data[time]}, ${data[crop]}