OscarAkaElvis OscarAkaElvis - 3 years ago 229
Bash Question

Bash. Checking array keys and values

I have in Bash (>=4.2) a peculiar scenario (data structure) that can't be changed. It's like this (not sure if this is called associative array or multidimensional array):

#!/bin/bash
declare -gA arrdata
arrdata["jimmy","vacation invoices"]="69008981"
arrdata["jimmy","budget"]="12345678 00392212"
arrdata["mike","budget"]="63859112 98005342 66675431"
arrdata["mike","extra"]="23332587"


We can say we have on this structure three kind of data. Name (jimmy or mike), type of expense (budget, extra or vacation invoices) and data (8 digit numbers separated as spaces). As I said it's important to the solution to maintain this strange structure for the array, can't be changed.

I need two functions. First one to check if somebody (a name) has a type of expense ("budget" or other). The function will receive two arguments, the name and the type required. For example:

#!/bin/bash
function check_if_expense_exist() {
#bash code array loops to return 0 if the type exist for the given name, 1 if not exist
}
#Expected results
#Given "jimmy" as first argument and "vacation invoices" as second should return 0
#Given "mike" as first argument and "vacation invoices" as second should return 1


The second function should check if a data is present. This will receive three arguments. The name ("jimmy" or "mike"), the type of expense ("budget" or other) and the data (a 8 digit number).

#!/bin/bash
function check_if_data_exist() {
#bash code array loops to return 0 if data exist for the given name and type of expense, 1 if not exist
}
#Expected results
#Given "jimmy" as first argument and "vacation invoices" as second, and "11111121" as third should return 1 because doesn't exist
#Given "mike" as first argument and "budget" as second, and "98005342" as third should return 0 because it exists


I can put here my unsuccessful approach but to be honest... it's painful. Loops inside loops trying to show data as separated vars... but it didn't worked. If somebody insist I can paste here but I hope some "bash guru" can guide me to a better way to handle this complex data structure (at least is complex for me). Thanks.

Answer Source

These functions can be very short:

$ check_if_expense_exist() { [[ -n "${arrdata["$1","$2"]:+not set}" ]]; }
$ check_if_expense_exist jimmy budget && echo y || echo n
y
$ check_if_expense_exist jimmy budgit && echo y || echo n
n
$ check_if_data_exist() { [[ "${arrdata["$1","$2"]}" =~ (^| )"$3"( |$) ]]; }
$ check_if_data_exist jimmy budget 12345678 && echo y || echo n
y
$ check_if_data_exist jimmy budget 1234568 && echo y || echo n
n
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download