0

I want to use a key-value storage in bash, and then access the elements and work with them. I have the following code so far, which finds the key in the storage, but can't extract the values from the array without interpreting the spaces.

A straight forward solution to this (since I know there will be three values for each key) is to access those directly, but surely there must be a way to slice the array properly.

# the array is a key: value storage, the keys do not contain spaces, but the values might
# there are always three values for each key, but the number of words in them is unknown
services=("key1" "some values" "another_value" "a lot of values"
          "key2" "other values" "simple_value2" "a lot of values here"
          "key3" "something else here" "another_value3" "whatever")

# this should look for the given value in the array and return the key and respective values if its found
function find_key () {
    arr=("${@:2}")
    len=$(( ${#arr[@]} -1 ))
    for i in $(seq 0 4 "$len")
    do
    if [[ ${arr[$i]} == "$1" ]] ; then
        # this should get the i'th element and 4 following elements (the values), which works correctly
        result="${arr[*]:$i:4}"
        # at this point result is just a regular array and there is no way to separate the values again

        # this prints just one line with all words
        for x in "${result[@]}"; do
            echo "element: '$x'"
        done

        # I want to return the array ("key" "value 1" "value 2" "the third value") from here to work with it later
        echo "${result[@]}"
        return 0
    fi
    done
    return 1
}

key_and_values="$(find_key "key2" "${services[@]}")"
echo "${key_and_values[@]}"

The output is:

element: 'key2 other values simple_value2 a lot of values here'
key2 other values simple_value2 a lot of values here

And I am looking for:

element: 'key2'
element: 'other values'
element: 'simple_value2'
element: 'a lot of values here'
key2 other values simple_value2 a lot of values here
2
  • "${key_and_values[@]}" key_and_values is not an array Commented Feb 19, 2020 at 10:38
  • No, it is not. The problem is at the line result="${arr[*]:$i:4}", where it changes from array to string Commented Feb 19, 2020 at 10:43

2 Answers 2

1

Change:

result="${arr[*]:$i:4}"

into an array:

result=("${arr[@]:$i:4}")

There are some problems with your script:

  • "${key_and_values[@]}" - key_and_values is not an array, it's a normal variable.
  • echo "${result[@]}" will work abnormally when for example result[0]='-n'. Use printf "%s\n" "${result[@]}" | paste -sd ' ' or similar.

I think I would go with something along:

find_key() {
    arr=("${@:2}")
    for ((i=0; i < ${#arr[@]}; i+=4)); do
        if [[ ${arr[$i]} == "$1" ]] ; then
            printf "%s\0" "${arr[@]:$i:4}"
            return 0
        fi
    done
    return 1
}

readarray -d '' -t key_and_values < <(find_key "key2" "${services[@]}")
printf "element: %s\n" "${key_and_values[@]}"
printf "%s\n" "${key_and_values[@]}" | paste -sd' '
Sign up to request clarification or add additional context in comments.

Comments

0

I use this tehniq in piu-piu

array=("abs 123 ---" "DEF 456 +++")
for items in "${array[@]}"; {
    sub=( $items )
    echo  ======
    for item in ${sub[@]}; {
        echo $item
    }
}

output

======
abs
123
---
======
DEF
456
+++

Also you can use an associative array and loop over indexes

declare -A items=( [item1]="123 abc" [item2]="dfe 234" )

for key in ${!items[@]}; {
    echo "key=$key"
    echo "val=${items[$key]}"
}

output

key=item2
val=dfe 234
key=item1
val=123 abc

But the question was about slicing right?), of course you can slice an array like this

array=("abs 123" "DEF 456" "ASA 789")

$ echo "${array[@]:1}"
DEF 456 ASA 789

$ echo "${array[@]::1}"
abs 123

$ echo "${array[@]:1:3}"
DEF 456 ASA 789

$ echo "${array[@]:1:1}"
DEF 456

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.