Sunday, September 4, 2022

[SOLVED] awk command with regex expression from variable fails

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)