Substituição de variável Bash em uma string JSON

Substituição de variável Bash em uma string JSON

Estou tentando criar um JSON no BASH onde um dos campos é baseado no resultado de um comando anterior

BIN=$(cat next_entry)
OUTDIR="/tmp/cpupower/${BIN}"
echo $OUTDIR
JSON="'"'{"hostname": "localhost", "outdir": "${OUTDIR}", "port": 20400, "size": 100000}'"'"
echo $JSON

O script acima quando executado retorna:

/tmp/cpupower/0
, port: 20400, size: 100000}': /tmp/cpupower/0

Como posso substituir corretamente variáveis ​​dentro dessas strings entre aspas múltiplas?

Responder1

JSON=\''{"hostname": "localhost", "outdir": "'"$OUTDIR"'", "port": 20400, "size": 100000}'\'

Isso é sair das aspas simples para a expansão de $OUTDIR. Colocamos essa expansão entre aspas duplas para garantir, embora para uma atribuição de variável escalar ela não seja estritamente necessária.

Quando você passa a $JSONvariável para echo, aspassãonecessário desabilitar o operador split+glob. Também é melhor evitar echodados arbitrários:

printf '%s\n' "$JSON"

Responder2

Se você acabou aqui tentando usar comandos AWS, a resposta de @Stéphane Chazelas quase funciona. Aqui, as aspas de escape iniciais (\') não são necessárias, elas na verdade quebram o comando.

IP=$(curl ipecho.net/plain ; echo)

aws ec2 authorize-security-group-ingress --group-id sg-**************** \
    --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 15000, "ToPort": 15000, "IpRanges": [{"CidrIp": "'"$IP/32"'", "Description": "Service A"}]}]'

^ Isso funciona muito bem

Responder3

A resposta de Stéphane é ótima e votada positivamente. Aqui vai apenas uma dica; em vez de fazer

BIN=$(cat next_entry)

Você pode fazer:

BIN=$(<next_entry)

E assim economize a geração de um processo extra. Consulte Mais informaçãoaqui.

Responder4

Se eu tiver um arquivo json parecido com eating.json= {"diner" : {"time" : ""}}, a maneira como faço é a seguinte:

declare -a NOW
NOW=$(date) 
jq '.diner.time = "'"${NOW}"'"' eating.json > tmp.$$.json && mv tmp.$$.json eating.json

Então, primeiro criei minha variável, depois coloquei o valor que queria nela e, por fim, usando jq, fiz a modificação em um arquivo temporário (especificidades do jqmódulo acredito), e depois coloquei as modificações de volta no eating.json.

informação relacionada