2

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

1
  • Why using different variables? You could us an associative array, where you have keys such as aspect_ratio, and fill in the value based on what's available in the output. Of course you need to know for this, which of the output lines denote the i.e. aspec ratio. Commented Oct 21, 2021 at 7:12

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This is PERFECT! Exactly what i wanted. Many thanks
Good to know it works. Cheers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.