#bash
Вопрос:
Я хочу проанализировать вывод 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 Nlt; lt;(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 кадров в секунду (строка 2), и он будет присвоен var B
Соотношение сторон 16:9 (строка 2), и оно было бы присвоено var B, должно было быть равно нулю
Комментарии:
1. Зачем использовать разные переменные? Вы могли бы создать ассоциативный массив, в котором у вас есть такие ключи , как
aspect_ratio
, и заполнить значение на основе того, что доступно в выходных данных. Конечно, для этого вам нужно знать, какая из выходных строк обозначает соотношение, т. е. aspec.
Ответ №1:
Поскольку вы полагаетесь на команду 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 lt; lt;(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]}" ...
хотя было бы удобнее рассматривать массив как массив.
Комментарии:
1. Это ПРЕКРАСНО! Именно то, чего я хотел. Большое спасибо
2. Приятно знать, что это работает. Ваше здоровье.