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.