Как назначить несколько переменных для вывода «таблицы» фиксированного размера

#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. Приятно знать, что это работает. Ваше здоровье.