Создание 2D массива из вывода команды в Bash - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь установить строки и столбцы из команды в многомерный массив для сравнения столбцов в каждой строке. Команда, которую я использую: (semanage login -l | more) Выходные данные:

Login Name           SELinux User         MLS/MCS Range        Service

__default__          user_u               s0                   *
user1                user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *

Мой текущий код устанавливает в каждой строке только индекс одномерного массива, как мне разделить каждый столбец (например: Имя для входа , SE Linux User, et c) из команды вывода в свои массивы или создать двумерный массив? Вот мой текущий код:

my_array=()
while IFS= read -ra line; do
    my_array+=("${line}")
    echo "${line}"
done < <(semanage login -l | more)

Ответы [ 2 ]

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

Одним из способов представления многомерного массива в bash 4 или более поздней версии является использование ассоциативного массива.

Вы получите строку, которая является объединением всех нужных вам индексов, и используйте это в качестве ассоциативного индекса.

Это действительно полезно, только если все, что вы хотите сделать, это l oop через элементы, и если вы хотите, чтобы схема сообщала об измерениях, вам нужно будет сохранить sh эти значения в качестве дополнительных членов.

declare -A myArray
myArray['!dims!']=2
myArray['!dim!0']=20
myArray['!dim!1']=z4

for x in {0..19} ;  do for y in {0..3} ; do 
   myArray["$x,$y"]=$value
done;done

Если вам нравится идея Чарльза использовать имя для входа в качестве первого индекса, хотя вы также должны будете сохранить список имен для входа. С моделью Чарльза вы можете запросить любой из списков для их значений индекса. Вы можете использовать имена столбцов в качестве второго индекса. Тогда вам нужно быть осторожным, чтобы разделитель имен , не использовался в качестве имени, или использовать другой символ-разделитель.

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

В bash нет поддержки многомерных массивов - но они вам не нужны для этого случая использования, когда число столбцов фиксировано и известно.

В качестве примера, который читает каждый столбец в другой ассоциативный массив, рассмотрим:

#!/usr/bin/env bash

get_data() {
  # in a real version this would run semanage login -l
  cat <<'EOF'
Login Name           SELinux User         MLS/MCS Range        Service

__default__          user_u               s0                   *
user1                user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *
EOF
}

declare -A selinux_users=() ranges=() services=()
{
  read _; read _ # discard header and leading blank line
  while read -r login_name selinux_user range service; do
    selinux_users[$login_name]=$selinux_user
    ranges[$login_name]=$range
    services[$login_name]=$service
  done
} < <(get_data)

# for debugging, print the result of the operation
declare -p selinux_users ranges services

... который выводит следующие определения массива:

declare -A selinux_users=([user1]="user_u" [__default__]="user_u" [root]="unconfined_u" )
declare -A ranges=([user1]="s0" [__default__]="s0" [root]="s0-s0:c0.c1023" )
declare -A services=([user1]="*" [__default__]="*" [root]="*" )
...