我最近被介绍到bash脚本的世界。我目前有一个文件视频,我想要持续时间。问题是将持续时间值分配给变量。我得到下面显示的错误。将持续时间值分配给变量的最佳方法是什么?还有两个greps是必要的。例如,第一个grep给出duration=171.805000
,然后我只需要为小数值做第二个grep。
段
#!/bin/bash/
str_duration=echo$(ffprobe -i "media/myvideo.mp4" -show_format -v quiet | grep duration)
int_duration=echo ${str_duration} | grep -o ' [0-9]\+\.[0-9]\+'
错误
line 15: echoduration=171.805000: command not found
命令输出
ffprobe version git-2014-12-27-d4fd3f2 Copyright (c) 2007-2014 the FFmpeg developers
built on Dec 27 2014 12:23:47 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
configuration: --enable-gpl --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
libavutil 54. 15.100 / 54. 15.100
libavcodec 56. 19.100 / 56. 19.100
libavformat 56. 16.102 / 56. 16.102
libavdevice 56. 3.100 / 56. 3.100
libavfilter 5. 6.100 / 5. 6.100
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/media/myvideo.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.16.102
Duration: 00:02:51.81, start: 0.000333, bitrate: 1504 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1367 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
handler_name : SoundHandler
duration=171.805000
答案 0 :(得分:2)
尝试类似:
str_duration=$(ffprobe -i "media/myvideo.mp4" -show_format -v quiet | grep duration | awk -F'=' '{print $2}')
你不需要回声。您的命令生成的输出也是:
duration=171.805000
你需要为str_duration变量分配数字,因此使用awk你得到的数字是" ="。
答案 1 :(得分:2)
所以......要回答有关错误的问题,您需要在echo
命令之后留出空格。
但等等,还有更多。
你可能真的不想要#34; echo"作为持续时间变量的一部分。您可以使用echo来显示某种类型的显示输出,而不是收集数据并将其存储在变量中。变量分配采用variable=value
或read variable
的形式,可以从各种来源获取值。
请注意,如果没有-v quiet
,ffprobe命令会将大量数据转储到stderr
,因此包含它以减少脚本噪音非常重要。
您的(安静的)ffprobe
命令的输出将包含以下内容:
duration=171.805000
你可以使用这种格式的数据做很多事情(我的天哪,它看起来像variable=value
...),但最简单的可能就是使用cut
。
file="media/myvideo.mp4"
str_duration=$(ffprobe -i "$file" -show_format -v quiet | grep ^duration | cut -d= -f2)
请注意,使用equals作为字段分隔符的这种方法可能会失败,因为其他字段可能包含它们自己的等号。但它应该是安全的持续时间。
或者,您可以使用awk
或sed
等工具来减少管道数量:
str_duration=$(ffprobe -i "$file" -show_format -v quiet | sed -ne '/^duration=/s///p')
或
str_duration=$(ffprobe -i "$file" -show_format -v quiet | awk -F= '$1=="duration"{print $2}')
我故意不告诉您如何使用eval
命令获取ffprobe的输出并将其直接指定为脚本中的变量,因为{如果您不检查并限制其输入,则{1}}命令非常危险。作为一个初学shell程序员,你应该阅读eval
然后不要使用它,直到你觉得你介于"中间"之间。和"高级"。 :)
或者,您可以使用输入字段分隔符在bash中解析此数据:
eval
这将获取ffprobe命令的输出并将其提交到数组的元素,您可以按照declare -A details
while IFS== read field value; do
details[$field]="$value"
done < <(ffprobe -i "$file" -show_format -v quiet | grep '.=.')
echo "${details[duration]}"
行读取该元素。由于echo
命令中提到的变量数量有限,因此包含等号的内容是安全的。
请注意,除了最后一个示例之外,此答案中的所有命令都与传统/ bin / sh兼容,而不仅仅是bash。