I have an array in bash script like
# myarr contains main elements (i.e. demo1, demo2) and "sub" elements (i.e. demo1%myspace1::myapp1)
# Inserting element in myarr occurs automatically in that order:
myarr=()
myarr =("demo1%myspace1::myapp1=param1#param2#param3")
myarr =("demo1%myspace1::myapp2=param1#param2#param3")
myarr =("demo1%myspace2::myapp1=param1#param2#param3")
myarr =("demo1=param1#param2#param3")
myarr =("demo2%myspace2::myapp1=param1#param2#param3")
myarr =("demo2%myspace2::myapp2=param1#param2#param3")
myarr =("demo2%myspace2::myapp3=param1#param2#param3")
myarr =("demo2=param1#param2#param3")
And I want to sort it so that "main" element comes before "sub" elements like:
"demo1=param1#param2#param3"
"demo1%myspace1::myapp1=param1#param2#param3"
"demo1%myspace1::myapp2=param1#param2#param3"
"demo1%myspace2::myapp1=param1#param2#param3"
"demo2=param1#param2#param3"
"demo2%myspace2::myapp1=param1#param2#param3"
"demo2%myspace2::myapp2=param1#param2#param3"
"demo2%myspace2::myapp3=param1#param2#param3"
After that, I want to print the array like:
demo1=param1#param2#param3
|
-- demo1%myspace1::myapp1=param1#param2#param3
-- demo1%myspace1::myapp2=param1#param2#param3
-- demo1%myspace2::myapp1=param1#param2#param3
demo2=param1#param2#param3
|
-- demo2%myspace2::myapp1=param1#param2#param3
-- demo2%myspace2::myapp2=param1#param2#param3
-- demo2%myspace2::myapp3=param1#param2#param3
Printing the sorted array is not the problem. Problem is how can I sort the array so that those "main"-elements comes before "sub"-elements?
PS: I use bash 3.2.54 and it doesn't support associative arrays.
CodePudding user response:
The key is to find the main elements from the array, then print each sub-element, sorted.
Here is one way to do it:
#!/bin/bash
myarr=()
myarr =("demo1%myspace1::myapp1=param1#param2#param3")
myarr =("demo1%myspace1::myapp2=param1#param2#param3")
myarr =("demo1%myspace2::myapp1=param1#param2#param3")
myarr =("demo1=param1#param2#param3")
myarr =("demo2%myspace2::myapp1=param1#param2#param3")
myarr =("demo2%myspace2::myapp2=param1#param2#param3")
myarr =("demo2%myspace2::myapp3=param1#param2#param3")
myarr =("demo2=param1#param2#param3")
for i in "${myarr[@]}"
do
# Find main elements
# A main element is something before a =, that does not include a %
firstelement=$(echo "$i" | cut -d'=' -f1)
if [[ ! "$firstelement" =~ % ]]
then
printf '\n%s\n' "$i"
printf ' |\n'
# Print the sub elements related to that main element
printf -- '%s\n' "${myarr[@]}" | grep -E "${firstelement}%.*::" | sort -n | sed -e 's/^/ -- /'
fi
done
I defined a main element as an array item that has some text, followed by =
, and that does not contain an %
sign. Ex. demo1
is a main, demo1%myspace1
is not.
The sed
is to add a prefix ( --
) to each sub-element.
That code produces the output you wanted:
demo1=param1#param2#param3
|
-- demo1%myspace1::myapp1=param1#param2#param3
-- demo1%myspace1::myapp2=param1#param2#param3
-- demo1%myspace2::myapp1=param1#param2#param3
demo2=param1#param2#param3
|
-- demo2%myspace2::myapp1=param1#param2#param3
-- demo2%myspace2::myapp2=param1#param2#param3
-- demo2%myspace2::myapp3=param1#param2#param3