как заполнить многострочный ассоциативный массив в bash - PullRequest
0 голосов
/ 20 февраля 2020

Я пытаюсь заполнить ассоциативный массив в bash из следующего файла примера

interface GigabitEthernet1/0/1
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp
interface GigabitEthernet1/0/2
 mls qos trust dscp
interface GigabitEthernet1/0/3
interface GigabitEthernet1/0/4
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp
interface GigabitEthernet1/0/5
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp
interface GigabitEthernet1/0/6
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp
interface GigabitEthernet1/0/7
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp
interface GigabitEthernet1/0/8
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp

interface GigabitEthernet1/0/1 или GigabitEthernet1/0/1 должен быть ключом массива, а что-либо между разделами интерфейса должно быть значением ключа массива.

 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp

Ожидаемый вывод должен быть:

 $echo ${array[GigabitEthernet1/0/4]}
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp

Будет несколько разных файлов с одинаковым форматом, так что это нужно сделать с помощью l oop, текст между интерфейсами должен быть от 0 до 5-6 строк. Причина в том, что мне нужно сделать логический тест на каждом интерфейсе, если он правильный или нет. Ниже текст верен, все остальное или пустое поле неверно.

 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp

До сих пор я придерживался форматирования IFS и мультилиней в качестве значения ключа массива. Мне удалось заполнить неассоциативный массив, но не в самой чистой форме.

$ cat test_compare_interface | sed 's/interface.*$/*\n&/g' > test_compare_interface_sed

test_compare_interface - файл с интерфейсами

$ IFS=$'*' && array=($(cat test_compare_interface_sed))
$ echo ${array[4]}

interface GigabitEthernet1/0/4
 srr-queue bandwidth share 10 10 60 20
 priority-queue out 
 mls qos trust dscp

С ассоциативным массивом l oop, я все еще борюсь

while IFS='*' read -r interface value; do array[$interface]=$value ; done < test_compare_interface_sed 

Спасибо за все предложения .

1 Ответ

0 голосов
/ 20 февраля 2020

Не могли бы вы попробовать следующее:

declare -A array

# assign "${val[*]}" to the assciative array "array" keying with $1
store() {
    if [[ -n $1 ]]; then        # will skip the 1st line which is not ready
        array[$1]=$(IFS=$'\n'; echo "${val[*]}")
                                # join "val" with newline
        unset val               # empty the queue
    fi
}

while IFS= read -r line; do
    if [[ $line =~ ^interface ]]; then
        store "$interface"      # assign to the associative array
        interface="$line"       # for the next iteration
    else
        val+=("${line# }")      # append to the queue
    fi
done < file.txt

store "$interface"              # flush the last entry

for i in "${!array[@]}"; do     # print the array elements to test
    echo "$i"
    echo "${array[$i]}"
done
  • Он просто читает строку ввода построчно без изменения IFS.
  • Если строка начинается с "interface" , он сбрасывает очередь (массив val) в ассоциативный массив и обновляет имя интерфейса для следующей итерации.
  • Если строка не начинается с «интерфейса», строка накапливается в очереди (массив val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...