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
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.
openssl rand -hex 36openssl command with the user name? My assumption is something like num=$(openssl <options> "$user"), where "$user" is a user name such as "foo" and the output is "123" which "num" is assigned to. Am I correct?openssl rand -hex 36. Resulting associative array is like - my_array=([foo]="e8db7...d7123" [baz]="4fb67....cfcb"users=(foo bar baz). Second, create an associative array declare -A users_with_password. Third, for user in ${users[@]}; do users_with_password["$user"]="$(openssl rand -hex 36)"; doneIf you just need to access a few keys then you could use a parameter expansion that strips everything but the value of interest from the bash array:
#!/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"
note: leading and trailing blanks will be stripped from 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
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
typeset -A my_array=(foo 123 bar 456 baz 789 lorem 012 ipsum 345)and then use${my_array[foo]}and${my_array[lorem]}?declare -A my_array=([foo]=123 [bar]=456 [baz]=789 [lorem]=012); echo "${my_array[foo]}", look for associative array5.1.16(1)-release.