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:
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? 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.
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.
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. With charles' model, you can ask any of the lists for their index values. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.