Issue
I am trying to fetch elements from array on the basis specific pattern for example: alllist is array contains following data:
echo "${alllist[@]}":
setup-demo1-release-0 setup-demo1-release-1 setup-demo1-release-2 setup-demo1-production-0 setup-demo1-production-1
where type is a variable and can have values like -release-0 and -production-0 ending with hyphen and numeric number
setup-demo1 is same for all elements in array and <-release-0> and <-production-0> so created a regex expression in which it will look for something like this: for type=release it shall return all values
setup-demo1-release-0 setup-demo1-release-1
for type=production it shall return all values
setup-demo1-production-0 setup-demo1-production-1
Note: setup-demo1 can also be written as setup-release1 or setup-production1 so using grep for these words shall be ignored.
I have also tried achieving this through awk command:
endWithDigitPattern='[-0-9]'
targetNodes=($(echo "$alllist"| sed 's/[][",]//g' | tr ' ' '\n' | awk -v nTypes="release""$endWithDigitPattern" '$1~ nTypes {print $1}'))
and it is not returning expected result while executed through script file. and may be I am not using endWithDigitPattern variable in right way.
Let me know what's wrong with my command used.
Solution
Setup:
$ alllist=(setup-demo1-release-0 setup-demo1-release-1 setup-demo1-release-2 setup-demo1-production-0 setup-demo1-production-1)
$ endWithDigitPattern='[-0-9]'
echo "$alllist"
is the same as echo "${alllist[0]}"
; to display the entire contents of the array we need to use echo "${alllist[@]}"
(keeping in mind this will not work as expected if the array values contain white space), eg:
$ typeset -p alllist
declare -a alllist=([0]="setup-demo1-release-0" [1]="setup-demo1-release-1" [2]="setup-demo1-release-2" [3]="setup-demo1-production-0" [4]="setup-demo1-production-1")
$ echo "$alllist" # references alllist[0]
setup-demo1-release-0
$ echo "${alllist[@]}"
setup-demo1-release-0 setup-demo1-release-1 setup-demo1-release-2 setup-demo1-production-0 setup-demo1-production-1
OP's current code:
$ echo "$alllist"| sed 's/[][",]//g' | tr ' ' '\n' | awk -v nTypes="release""$endWithDigitPattern" '$1~ nTypes {print $1}'
setup-demo1-release-0
Fix to OP's current code:
$ echo "${alllist[@]}"| sed 's/[][",]//g' |tr ' ' '\n' | awk -v nTypes="release""$endWithDigitPattern" '$1~ nTypes {print $1}'
setup-demo1-release-0
setup-demo1-release-1
setup-demo1-release-2
Assuming we can ignore the possibility of white space within the array values, there are a few other ways to to perform the desired operation; one idea using printf|grep
:
$ type=production
$ printf "%s\n" "${alllist[@]}" | grep -- "-${type}-[0-9]"
setup-demo1-production-0
setup-demo1-production-1
$ type=release
$ printf "%s\n" "${alllist[@]}" | grep -- "-${type}-[0-9]"
setup-demo1-release-0
setup-demo1-release-1
setup-demo1-release-2
Answered By - markp-fuso Answer Checked By - Timothy Miller (WPSolving Admin)