为变量赋值命令输出的grep值

时间:2015-05-01 15:07:33

标签: linux bash unix

我最近被介绍到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

2 个答案:

答案 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=valueread 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作为字段分隔符的这种方法可能会失败,因为其他字段可能包含它们自己的等号。但它应该是安全的持续时间。

或者,您可以使用awksed等工具来减少管道数量:

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。