从输出中提取某些信息

从输出中提取某些信息

我正在尝试从 ffmpeg 输出中提取某些信息。

ffmpeg 输出示例:

configuration:  --enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook --disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264 
libavutil version: 49.0.0
libavcodec version: 51.9.0
libavformat version: 50.4.0
built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file.mov':
Duration: 00:01:32.0, start: 0.000000, bitrate: 63489 kb/s
Stream #0.0(eng): Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream #0.1(eng), 29.97 fps(r): Video: Apple ProRes 422, 1280x720
Must supply at least one output file

我想返回一个仅包含持续时间、帧速率、编解码器和大小的字符串,例如:

[00:01:32_29.97_Apple ProRes 422_1280x720]

我尝试从这个开始(来自另一个提示):

ffmpeg -i file.mov 2>&1 | sed -n 's/Duration: \(.*\), start/\1/gp'

获取持续时间,但这只是“删除”了Durationand , start,即:

00:01:32.0: 0.000000, bitrate: 63489 kb/s

PS:我还想从中Apple删除Apple ProRes 422:-)

谢谢!

更新:我能够使用以下命令提取编解码器

sed -n "s/.*\Video: \(.*\),.*/\1/p"

但我不知道如何(a)获取大小和帧速率,以及(b)将搜索合并到一行......

答案1

awk:这就像魔法,但更好。

#!/usr/bin/awk -f
/Duration/ {sub(/,/, "", $2); fields["dur"] = $2}
/fps/ { fields["fps"] = $3 }
/Video/ { 
        sub(/.*Video:/, "", $0);
        sub(/\W*Apple\W*/, "", $0);
        split($0, arr, ", ")
        fields["codec"] = arr[1]; 
        fields["res"] = arr[2]; 
}
END {
        printf "[%s_%s_%s_%s]\n", 
                fields["dur"], 
                fields["fps"], 
                fields["codec"],  
                fields["res"]
}

答案2

要在 sed 中提取行的一部分,请匹配整行,并使用反向引用打印出您想要保留的位。 (如果您的 sed 没有\+运算符,请使用foo*代替fo\+。)

$ … | sed -n -e 's/^.*Duration: *\([^,]*\).*$/\1/p' \
             -e 's/^.* \([0-9.]\+\) fps(r).* Video: \([^,]\+\).*, *\([0-9]\+x[0-9]\+\).*$//'
00:01:32.0
29.97 Apple ProRes 422 1280x720

请注意,当有多种方法来决定哪些文本进入哪个组时,较早的组将尽可能长。例如,在第二个表达式的开头,^.* \([0-9.]\+\) fps匹配空格后的数字;如果表达式是,^.*\([0-9.]\+\) fps则组内只有一位数字会匹配,较早的数字将被 吸收.*。相反,在第二个表达式的末尾,\([0-9]\+\).*$将所有数字放入组内,只有当无法再匹配.*时才开始,即在第一个非数字之后。[0-9]\+

虽然有可能,但 sed 不擅长组合多行或进行后处理。当您的需求超出简单的文本替换时,转向 awk

答案3

您可以在同一个sed命令上添加多个表达式 - 如果您添加一些内容以从视频流行中提取“Apple”,它仍然会打印两个匹配项以及替换项。

唯一的问题是它会以两条不同的行打印,但你总是可以|xargs echo或更优雅的方式。

答案4

您可以使用sedwith-e选项来组合多个条件,如下所示:

sed -e <expression1> -e <expression2> ...

相关内容