首页 > 解决方案 > 如何将多个变量分配给固定大小的“表”输出

问题描述

我想解析一个mediainfo输出并将每一行分配给它自己的变量。

我的问题是,如果输出的行数发生变化,那么 var 的逻辑值也会发生变化。

#!/usr/bin/env bash

function tester_mediainfo() {
    
    #this must be done with the hard new line, its a mediainfo quirk 
template="General;%OverallBitRate/String%|
Video;%Width%|%Height%|%FrameRate/String%|%DisplayAspectRatio/String%|%ScanType/String%|%FrameRate/String%|%ChromaSubsampling/String%|%BitDepth%|%InternetMediaType%|%Format/String%|%Format_Profile%|%Format_Settings%|%BitRate_Mode/String%|%BitRate_Nominal/String%|%BitRate_Maximum/String%|%ColorSpace%|
Audio;%BitRate/String%|%Format/String%|%Channel(s)/String%|%BitRate_Mode/String%|%BitRate/String%|%SamplingRate/String%"

maker=$(mediainfo --Output="$template" "$1" | sed 's/video\///g' | tr '|' '\n '| awk '{ print $1 }')

read -r A B C D E F G H I J K L M N< <(echo $maker)
}

tester_mediainfo $1

我希望能够输出一个变量列表,以便稍后在IF语句中使用,因此它们的逻辑含义不能改变!

假设脚本输出:

output:     variable:
15.7            A 
25.000      B                   #this changes 
16:9            C
MBAFF           D
25.000      E           #this changes 
4:2:0           F
8                   G
H264            H
AVC             I
High            J
CABAC           K

那是 11 行输出。

现在,如果我在不同的媒体文件上再次运行脚本,会发生什么:

output:     variable:
10.5                A
16:9                B
Progressive C
4:2:0               D
8                       E
H264                F
AVC                 G
Main@L4.1       H
CABAC               I
Constant        J
10                  K

25.000 FPS(第 2 行)并将分配给 var B

16:9纵横比 (line2) 并将分配给 var B 应该为空

标签: bash

解决方案


由于您依赖命令word splitting中的read,因此会将连续的空值放在一起导致结果不一致。

请您尝试一下:

# no changes in your original template
template="General;%OverallBitRate/String%|
Video;%Width%|%Height%|%FrameRate/String%|%DisplayAspectRatio/String%|%ScanType/String%|%FrameRate/String%|%ChromaSubsampling/String%|%BitDepth%|%InternetMediaType%|%Format/String%|%Format_Profile%|%Format_Settings%|%BitRate_Mode/String%|%BitRate_Nominal/String%|%BitRate_Maximum/String%|%ColorSpace%|
Audio;%BitRate/String%|%Format/String%|%Channel(s)/String%|%BitRate_Mode/String%|%BitRate/String%|%SamplingRate/String%"

mapfile -t info < <(mediainfo --Output="$template" "$1" | sed 's/video\///g' | tr '|' '\n' | awk '{ print $1 }')

for i in "${info[@]}"; do
    echo "$i"
done

mapfile内置命令从标准输入中读取行,并为每行分配一个数组(此处info)。它保留空行as is,然后结果始终具有相同的长度。如果要将单个标量变量分配给数组的元素,可以这样说:

A="${info[0]}"
B="${info[1]}"
C="${info[2]}"
...

尽管将数组视为数组会更方便。


推荐阅读