Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 为变量赋值命令输出的grep值_Linux_Bash_Unix - Fatal编程技术网

Linux 为变量赋值命令输出的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)

我最近被介绍到bash脚本的世界。我目前有一个视频文件,我想grep的持续时间。问题是将持续时间值分配给变量。我得到如下所示的错误。为变量指定持续时间值的最佳方法是什么?也有必要有两个grep。例如,第一个grep给出
持续时间=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 posted
ffprobe-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]}"