首页 > 解决方案 > 如何在bash中填充多行关联数组

问题描述

我正在尝试从以下示例文件中填充 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/1or 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

会有多个不同的文件格式相似,所以需要循环执行,界面之间的文本应该是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

使用关联数组循环,我仍在苦苦挣扎

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

感谢您的所有建议。

标签: arraysbash

解决方案


请您尝试以下方法:

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)刷新到关联数组中并更新接口名称以进行下一次迭代。
  • 如果该行不以“interface”开头,则该行在队列中累积(数组val

推荐阅读