简体   繁体   English

从 Bash 中的命令输出创建二维数组

[英]Creating 2D Array from command output in Bash

I am trying to set the rows and columns from a command into a multi-dimensional array to compare columns in each row.我试图将命令中的行和列设置为多维数组以比较每行中的列。 The command I am using is: (semanage login -l | more) The output is:我使用的命令是: (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       *

My current code only sets each row to an index of a 1D array, how do I either separate each column (ex: Login Name, SELinux User, etc) from the command output into their own arrays, or create a 2D array?我当前的代码只将每一行设置为一维数组的索引,我如何将命令输出中的每一列(例如:登录名、SELinux 用户等)分隔到它们自己的数组中,或者创建一个二维数组? Here is my current code:这是我当前的代码:

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

There is no support for multidimensional arrays in bash -- but you don't need them for this use case, where the number of columns is fixed and known. bash 中不支持多维数组——但在这个用例中不需要它们,其中列数是固定的和已知的。

As an example that reads each column into a different associative array, consider:作为将每一列读入不同关联数组的示例,请考虑:

#!/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

...which emits as output the following array definitions: ...它发出以下数组定义作为输出:

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]="*" )

One way to represent a multi-dimension array in bash 4 or later would be to use an associative array.在 bash 4 或更高版本中表示多维数组的一种方法是使用关联数组。

You would produce a string which is the concatenation of all the indices you want, and use that as the associative index.您将生成一个字符串,它是您想要的所有索引的串联,并将其用作关联索引。

This is only really useful if all you want to do is loop through the elements, and if you want the schema to report back the dimensions then you would need to stash those values as extra members.这仅在您只想遍历元素时才真正有用,并且如果您希望架构报告维度,那么您需要将这些值作为额外成员存储。

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

If you like @Charles's idea of using the login name as the first index you can, though you would also need to keep a list of the login names.如果您喜欢@Charles 使用登录名作为第一个索引的想法,尽管您还需要保留一个登录名列表。 With charles' model, you can ask any of the lists for their index values.使用 charles 模型,您可以询问任何列表的索引值。 You can use the column names as the second index.您可以使用列名作为第二个索引。 You would then need to be careful that the name separator , is not used as a name, though, or use a different separator character.然后,您需要注意名称分隔符,不被用作名称,或者使用不同的分隔符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM