Retorna a saída de um comando para um array associativo

5

Eu preciso colocar a saída de um comando em um array associativo.

Por exemplo:

dig mx +short google.com

retornará:

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.

Como posso criar um array associativo usando as prioridades (10,20, ...) como chave e o registro (aspmx.l.google.com.) como o valor?

    
por fidelity 01.04.2017 / 08:31

4 respostas

7

Aqui está uma maneira de ler esses dados em uma matriz associativa bash:

Código:

#!/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

Saída:

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.
    
por 01.04.2017 / 09:07
1
Em primeiro lugar, acho que a solução de Stephen Rauch (ao lado do comentário de chepner) é ótima. Mas quando se trata de matrizes associativas , eu quase sempre uso dicionários em Python, não porque eu não gosto de Bash, mas porque eles são (na minha opinião) mais fáceis de trabalhar em uma linguagem de nível superior.

Abaixo está um exemplo de uso em 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)

Execução:

./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."
}

novamente; a solução acima no Bash é ótima (e votada por mim). Este é apenas mais um exemplo em Python, nada mais.

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

Primeiro, declare uma matriz associativa chamada mx , execute dig e use sed para converter a saída em atribuições de matriz associativa e, em seguida, eval no shell atual. O comando sed retira todas as aspas simples e, em seguida, encapsula a atribuição da variável, usando aspas simples para citar o valor.

    
por 04.04.2017 / 01:37
0

Você pode usar o separador de campo interno para separar a entrada em linhas

 IFS="\n" read -ra ADDR <<< "$IN"
    
por 01.04.2017 / 11:49