Linux 为变量赋值命令输出的grep值
我最近被介绍到bash脚本的世界。我目前有一个视频文件,我想grep的持续时间。问题是将持续时间值分配给变量。我得到如下所示的错误。为变量指定持续时间值的最佳方法是什么?也有必要有两个grep。例如,第一个grep给出Linux 为变量赋值命令输出的grep值,linux,bash,unix,Linux,Bash,Unix,我最近被介绍到bash脚本的世界。我目前有一个视频文件,我想grep的持续时间。问题是将持续时间值分配给变量。我得到如下所示的错误。为变量指定持续时间值的最佳方法是什么?也有必要有两个grep。例如,第一个grep给出持续时间=171.805000,然后我必须只对十进制值执行第二个grep 片段 #!/bin/bash/ str_duration=echo$(ffprobe -i "media/myvideo.mp4" -show_format -v quiet | 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]\+'
错误
命令输出
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
尝试以下方法:
str_duration=$(ffprobe -i "media/myvideo.mp4" -show_format -v quiet | grep duration | awk -F'=' '{print $2}')
你不需要回声。此外,您的命令生成的输出为:
duration=171.805000
您需要为str_duration变量分配数字,因此使用awk,您可以得到“=”之后的数字,我将使用:
duration=$( ffprobe -i "media/myvideo.mp4" -show_format -v quiet | grep duration | sed 's/.*=//g' )
如果您只想输入号码:
duration=$( ffprobe -i "media/myvideo.mp4" -show_format -v quiet | grep ^duration | sed -e 's/.*=//' -e 's/\..*//' )
所以。。。要回答有关错误的问题,需要在
echo
命令后加上空格
但是等等,还有更多
您可能并不真的希望“echo”这个词作为持续时间变量的一部分。您应该使用echo来显示某种输出,而不是收集数据并将其存储在变量中。变量分配的形式为Variable=value
或readvariable
,可以从各种来源获取值
请注意,如果没有-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)
请注意,这种将等号用作字段分隔符的方法可能会失败,因为其他字段可能包含它们自己的等号。但在整个过程中应该是安全的
或者,您可以使用awk
或sed
等工具来减少管道数量:
str_duration=$(ffprobe -i "$file" -show_format -v quiet | sed -ne '/^duration=/s///p')
或
我故意不告诉您如何使用eval
命令获取ffprobe的输出,并将其直接作为脚本中的变量分配,因为如果不检查和限制其输入,eval
命令非常危险。作为一名初级shell程序员,您应该阅读eval
,然后在感觉自己处于“中级”和“高级”之间之前不要使用它:)
或者,您可以使用输入字段分隔符在bash中解析此数据:
declare -A details
while IFS== read field value; do
details[$field]="$value"
done < <(ffprobe -i "$file" -show_format -v quiet | grep '.=.')
echo "${details[duration]}"
declare-A详细信息
而IFS==读取字段值;做
详细信息[$field]=“$value”
完成ffprobe-i“media/myvideo.mp4”-show_format-v quiet
@Sobrique output postedffprobe-i“media/myvideo.mp4”-show_format-v quiet
@Sobrique output?(…| sed-n'/duration/s.*=/gp'
)如果要将awk
添加到管道中,为什么要将grep
留在那里?经过一些考虑,这是最好的答案。然而,我得到了这个错误第18行:当读取字段值时,意外标记do'IFS==附近的语法错误;执行
操作时,echo“${details[duration]”缺少一个{
,这是我的想法。IFS
作业需要应用于read
命令,而不是while
。我已经更正了答案中的错误,请使用更正的命令行重试。谢谢!)
str_duration=$(ffprobe -i "$file" -show_format -v quiet | awk -F= '$1=="duration"{print $2}')
declare -A details
while IFS== read field value; do
details[$field]="$value"
done < <(ffprobe -i "$file" -show_format -v quiet | grep '.=.')
echo "${details[duration]}"