Home > Software design >  How to assign multiple variables to a FIXED sized "table" output
How to assign multiple variables to a FIXED sized "table" output

Time:10-22

I want to parse a mediainfo output and assign each line to its own variable.

My problem is that if the number of lines of the output changes, then the logical value of the var also changes.

#!/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

I want to be able to output a list of variables to be used in IF statements later, thus the logical meaning of them cannot change!

let's say the script outputs:

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

that's 11 lines of output.

Right now, what happens is that if I run the script again on a different mediafile:

output:     variable:
10.5                A
16:9                B
Progressive C
4:2:0               D
8                       E
H264                F
AVC                 G
[email protected]       H
CABAC               I
Constant        J
10                  K

25.000 FPS (line 2) and it would be assigned to var B

16:9 Aspect Ratio (line2) and it would be assigned to var B should have been null

CodePudding user response:

As you are relying on the word splitting in the read command, succesive empty values are put together to cause inconsistency in the result.

Would you please try instead:

# 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

The mapfile built-in command reads lines from the standard input assigning an array (info here) to each lines. It preserves the empty line as is then the result has always the same length. If you want to assign individual scalar variables to the elements of the array, you can say something like:

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

although it would be more convenient to treat the array as an array.

  •  Tags:  
  • bash
  • Related