I have an array
my_array=(foo:123 bar:456 baz:789 lorem:012 ipsum:345)
I want to extract the value after delimiter for a given key
eg. passing foo
should return 123. Similarly, passing lorem
should return 012
CodePudding user response:
If it is acceptable to prepare another (associative) array variable, how about:
#!/bin/bash
my_array=(foo:123 bar:456 baz:789 lorem:012 ipsum:345)
declare -A $(printf "%s\n" "${my_array[@]}" | sed 's/\(.*\):\(.*\)/my_array2[\1]=\2/')
declare -p my_array2
Output:
declare -A my_array2=([bar]="456" [baz]="789" [foo]="123" [lorem]="012" [ipsum]="345" )
Then echo "${my_array2[foo]}"
will output 123
as an example.
Please note passing variables or command outputs to declare
has a possible
vulnerability risk. Make sure the strings in my_array
are fully under control.
CodePudding user response:
If you just need to access a few keys then you might consider something like:
#!/bin/bash
shopt -s extglob
my_array=(foo:123 bar:456 baz:789 lorem:012 ipsum:345)
my_key=lorem
my_val=${my_array[@]/@("$my_key":|!("$my_key":*))/}
echo "$my_val"
012
If you'll be accessing a lot of keys then the previous method is too inefficient so you'll need to build an associative array (bash 4 ):
#!/bin/bash
my_array=(foo:123 bar:456 baz:789 lorem:012 ipsum:345)
declare -A my_hash
for elem in "${my_array[@]}"
do
IFS=':' read -r key val <<< "$elem"
my_hash["$key"]=$val
done
echo "${my_hash[lorem]}"
012
CodePudding user response:
If you are using older bash versions where associative arrays are not available you could use bash regex matching and parameter substitution:
#!/bin/bash
pattern=${1:-lorem}
arr=(foo:123 bar:456 baz:789 lorem:012 ipsum:345)
for i in "${arr[@]}" ; do
if [[ "${i}" =~ ^${pattern}:* ]] ; then
echo "${i##*:}"
fi
done
Output:
$ ./foo.sh # default pattern is lorem
012
$ ./script foo
123
$ ./script bar
456
$ ./script baz
789
$ ./script lorem
012
$ ./script ipsum
345