I am facing the following issue and cannot think of a way to iterate multiple arrays from within one parent for loop.
For example, the current code is this:
main_array=("STRING1" "STRING2" "STRING3")
array1=(1 2 3)
array2=(4 5 6)
array3=(7 8 9)
I need the code that will print following output:
STRING1
1
2
3
STRING2
4
5
6
STRING3
7
8
9
In essence, I need for loop that iterates through main_array (see above), then inside that loop another for loop that iterates array1. Once finished, parent for loop prints STRING2, then iterates throgh array2, and so on.
EDIT:
Here is my (truncated) attempt:
packages=("NETWORK" "FILE_SYSTEM")
NETWORK=(DBMS_LDAP UTL_INADDR UTL_TCP UTL_MAIL UTL_SMTP UTL_DBWS UTL_ORAMTS UTL_HTTP HTTPURITYPE)
FILE_SYSTEM=(DBMS_ADVISOR DBMS_LOB UTL_FILE)
for package in "${packages[@]}"; do
echo "Ensure 'EXECUTE' is revoked from 'PUBLIC' on $package Packages"
for i in ${NETWORK[@]}; do
/bin/echo -e "Current setting for $i:"
RESULT=$(grep -Ei "^PUBLIC;.*$i;.*EXECUTE.*" file.txt)
if [[ -z "$RESULT" ]]; then
/bin/echo -e "Setting for $i is properly configured.\n"
else
/bin/echo -e "[!] This is not recommended setting! EXECUTE privilege should not be enabled for $i\n"
fi
done
done
OUTPUT:
======================================================================
Ensure 'EXECUTE' is revoked from 'PUBLIC' on NETWORK Packages
======================================================================
[ ] Current setting for DBMS_LDAP:
PUBLIC;SYS;DBMS_LDAP;SYS;EXECUTE;NO;NO
[!] This is not recommended setting! EXECUTE privilege should not be enabled for DBMS_LDAP
[ ] Current setting for UTL_INADDR:
PUBLIC;SYS;UTL_INADDR;SYS;EXECUTE;NO;NO
[!] This is not recommended setting! EXECUTE privilege should not be enabled for UTL_INADDR
***TRUNCATED REPETITIVE - REST OF NETWORK ARRAY IS PRINTED HERE***
***CHILD FOR LOOP IS OVER, MAIN ARRAY STARTS***
======================================================================
Ensure 'EXECUTE' is revoked from 'PUBLIC' on FILE SYSTEM Packages
======================================================================
[ ] Current setting for DBMS_LDAP:
**##### Issue here, needs to iterate values from FILESYSTEM array**
PUBLIC;SYS;DBMS_LDAP;SYS;EXECUTE;NO;NO
[!] This is not recommended setting! EXECUTE privilege should not be enabled for DBMS_LDAP
Thank you!
CodePudding user response:
OP has provided two sets of input arrays which are going to require slightly different solutions ...
Looking at the 1st set of arrays:
$ typeset -p main_array array1 array2 array3
declare -a main_array=([0]="STRING1" [1]="STRING2" [2]="STRING3")
declare -a array1=([0]="1" [1]="2" [2]="3")
declare -a array2=([0]="4" [1]="5" [2]="6")
declare -a array3=([0]="7" [1]="8" [2]="9")
Looks like we can just loop based on the numerical indexes of the main_array[]
array while using a nameref
to dynamically pick the appropriate array#
array ...
One idea:
for ((i=0; i<${#main_array[@]}; i ))
do
echo "${main_array[i]}"
declare -n curr_array="array$((i 1))" # nameref
for ((j=0; j<"${#curr_array[@]}"; j ))
do
echo "${curr_array[j]}"
done
done
This generates:
STRING1
1
2
3
STRING2
4
5
6
STRING3
7
8
9
Looking at the 2nd set of arrays:
$ typeset -p packages NETWORK FILE_SYSTEM
declare -a packages=([0]="NETWORK" [1]="FILE_SYSTEM")
declare -a NETWORK=([0]="DBMS_LDAP" [1]="UTL_INADDR" [2]="UTL_TCP" [3]="UTL_MAIL" [4]="UTL_SMTP" [5]="UTL_DBWS" [6]="UTL_ORAMTS" [7]="UTL_HTTP" [8]="HTTPURITYPE")
declare -a FILE_SYSTEM=([0]="DBMS_ADVISOR" [1]="DBMS_LOB" [2]="UTL_FILE")
A slight variation will have us using the value of the packages[]
array, as opposed to the index, to determine the nameref
, eg:
for ((i=0; i<${#packages[@]}; i ))
do
echo "${packages[i]}"
declare -n curr_array="${packages[i]}" # nameref
for ((j=0; j<"${#curr_array[@]}"; j ))
do
echo " ${curr_array[j]}"
done
done
This generates:
NETWORK
DBMS_LDAP
UTL_INADDR
UTL_TCP
UTL_MAIL
UTL_SMTP
UTL_DBWS
UTL_ORAMTS
UTL_HTTP
HTTPURITYPE
FILE_SYSTEM
DBMS_ADVISOR
DBMS_LOB
UTL_FILE
NOTE:
Both solutions use the same inner loop to process the nameref
array via index:
for ((j=0; j<"${#curr_array[@]}"; j ))
do
echo "${curr_array[j]}"
done
A couple alternative methods for looping through the nameref
array:
for j in "${!curr_array[@]}" # loop through indexes
do
echo "${curr_array[j]}"
done
##########
for j in "${curr_array[@]}" # loop through values
do
echo "$j"
done
CodePudding user response:
Here's a truncated version of your truncated attempt, with old school nameref:
#!/bin/bash
packages=("NETWORK" "FILE_SYSTEM")
NETWORK=(DBMS_LDAP UTL_INADDR UTL_TCP UTL_MAIL UTL_SMTP UTL_DBWS UTL_ORAMTS UTL_HTTP HTTPURITYPE)
FILE_SYSTEM=(DBMS_ADVISOR DBMS_LOB UTL_FILE)
for package in "${packages[@]}"
do
echo "=== $package ==="
array_ref="$package[@]"
for i in "${!array_ref}"
do
echo "$i"
done
done
=== NETWORK ===
DBMS_LDAP
UTL_INADDR
UTL_TCP
UTL_MAIL
UTL_SMTP
UTL_DBWS
UTL_ORAMTS
UTL_HTTP
HTTPURITYPE
=== FILE_SYSTEM ===
DBMS_ADVISOR
DBMS_LOB
UTL_FILE
CodePudding user response:
Yes, you have the wrong data structure:
typeset -p array1 array2 array3
declare -a array1=([0]="STRING1" [1]="1" [2]="2" [3]="3")
declare -a array2=([0]="STRING2" [1]="4" [2]="5" [3]="6")
declare -a array3=([0]="STRING3" [1]="7" [2]="8" [3]="9")
I see no reason to split things out.