5

I need to put the output of a command into an associative array.

For example:

dig mx +short google.com

Will return:

20 alt1.aspmx.l.google.com.
40 alt3.aspmx.l.google.com.
50 alt4.aspmx.l.google.com.
10 aspmx.l.google.com.
30 alt2.aspmx.l.google.com.

How can I create an associative array using the priorities (10,20,...) as the key and the record (aspmx.l.google.com.) as the value?

  • If any of the existing answers solves your problem, please consider accepting it via the checkmark. Thank you! – Jeff Schaller Apr 25 '17 at 10:40
7

Here is one way to read that data into a bash associative array:

Code:

#!/usr/bin/env bash
declare -A hosts
while IFS=" " read -r priority host ; do
  hosts["$priority"]="$host"
done < <(dig mx +short google.com)    

for priority in "${!hosts[@]}" ; do
  echo "$priority -> ${hosts[$priority]}"
done

Output:

20 -> alt1.aspmx.l.google.com.
10 -> aspmx.l.google.com.
50 -> alt4.aspmx.l.google.com.
40 -> alt3.aspmx.l.google.com.
30 -> alt2.aspmx.l.google.com.
  • 2
    There's no real need for the other array; just use two variables (which makes the code more readable as well): while read -r f1 host; do assoc[$f1]=$host; done. (There is certainly a better name than f1 for the first field, but I'm too lazy to look up what that value actually is.) – chepner Apr 1 '17 at 13:03
  • @chepner, thank you. This missing variable name is priority. (or distance, or preference) – Stephen Rauch Apr 1 '17 at 14:54
1

First of all, I think Stephen Rauch's solution (alongside chepner's comment) is great. But when it comes to associative arrays, I almost always use dictionaries in Python, not because I don't like Bash, but because they are (in my opinion) easier to work with in a higher level language.

Below is an example of usage in Python.

#!/usr/bin/env python3

import subprocess
import os
import json

digDict = {}
tmpOut = open("tmpOut", "w")
output = subprocess.call(['dig', 'mx', '+short', 'google.com'], stdout=tmpOut)

# Fill the dictionary with the values we want
with open("tmpOut") as infile:
    for line in infile:
        digDict[line.split()[0]] = line.split()[1]

os.remove("tmpOut")

# Sort the dictionary by key
print("Sorted dictionary:")
for key in sorted(digDict):
    print(key + " -> " + digDict[key])

# Get a specific value based on key
print("Access value associated with key '10' (digDict[\"10\"]):")
print(digDict["10"])

# "Pretty print" the dictionary in json format
print("json format:")
print(json.dumps(digDict, sort_keys=True, indent=4))

# Saved the dictionary to file in json format
with open("digDict.json", "w") as fp:
    json.dump(digDict, fp, sort_keys=True, indent=4)

exit(0)

Execution:

./myDig.py 
Sorted dictionary:
10 -> aspmx.l.google.com.
20 -> alt1.aspmx.l.google.com.
30 -> alt2.aspmx.l.google.com.
40 -> alt3.aspmx.l.google.com.
50 -> alt4.aspmx.l.google.com.
Access value associated with key '10' (digDict["10"]):
aspmx.l.google.com.
json format:
{
    "10": "aspmx.l.google.com.",
    "20": "alt1.aspmx.l.google.com.",
    "30": "alt2.aspmx.l.google.com.",
    "40": "alt3.aspmx.l.google.com.",
    "50": "alt4.aspmx.l.google.com."
}

cat digDict.json:

{
    "10": "aspmx.l.google.com.",
    "20": "alt1.aspmx.l.google.com.",
    "30": "alt2.aspmx.l.google.com.",
    "40": "alt3.aspmx.l.google.com.",
    "50": "alt4.aspmx.l.google.com."
}

Again; the solution above in Bash is great (and upvoted by me). This is just another example in Python, nothing more.

1
declare -A mx
eval $(dig mx +short google.com | sed "s/'//g; s/^/mx[/; s/ /]='/; s/$/';/")

First declare an associative array named mx, then execute dig and used sed to convert the output into associative array assignments, then eval that into the current shell. The sed command strips all single quotes, then wraps the variable assignment in, using single-quotes to quote the value.

0

You can use the internal field separator to separate the input into lines

 IFS="\n" read -ra ADDR <<< "$IN"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.