Como faço para escapar do ponto e vírgula na string com o Bash

Como faço para escapar do ponto e vírgula na string com o Bash

Recebi a string JSON abaixo que uso para alimentar o aws route53 change-resource-record-setscomando para atualizar um registro DMARC atual. Como você pode ver, o valor TXT contém ;.

JSON="{ \"Comment\": \"Updating TXT record in $domain\", 
  \"Changes\": [ { \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\": 
  \"_dmarc.${domainName}\", \"Type\": \"TXT\", \"TTL\": 
  3600, \"ResourceRecords\": [ { \"Value\": "\"v=DMARC1\; p=reject\; pct=100\"" } ] } } ] }"

Quando eu echo $JSON, em vez de toda a string JSON, obtive a saída abaixo. Parece que a análise para assim que atinge ;.

{ "Comment": "Updating TXT record in ", 
  "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": 
  "_dmarc.contoso.com", "Type": "TXT", "TTL": 
  3600, "ResourceRecords": [ { "Value": "v=DMARC1;

Eu tentei várias maneiras de escapar do ponto e vírgula, como usando \\;e \";\"sem sorte. O que eu fiz de errado aqui?

Responder1

Basta usar uma mistura de aspas simples e duplas e assim não parecerá tão confuso e será mais fácil de trabalhar:

JSON='{ "Comment": "Updating TXT record in $domain", 
  "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": 
  "_dmarc.${domainName}", "Type": "TXT", "TTL":  
  3600, "ResourceRecords": [ { "Value": "v=DMARC1; p=reject; pct=100" } ] } } ] }'

Este funciona. Exemplo:

$ JSON='{ "Comment": "Updating TXT record in $domain",
  "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name":
  "_dmarc.${domainName}", "Type": "TXT", "TTL":
  3600, "ResourceRecords": [ { "Value": "v=DMARC1; p=reject; pct=100" } ] } } ] }'
$
$ echo $JSON | jq .
{
  "Comment": "Updating TXT record in $domain",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "_dmarc.${domainName}",
        "Type": "TXT",
        "TTL": 3600,
        "ResourceRecords": [
          {
            "Value": "v=DMARC1; p=reject; pct=100"
          }
        ]
      }
    }
  ]
}
$

Responder2

Acontece que o problema aqui não é escapar do ponto e vírgula, mas do espaço à direita após o ponto e vírgula. Depois que mudei a string para algo assim

{ \"Value\": "\"v=DMARC1\;\ p=reject\;\ pct=100\"" }

A string agora ecoa corretamente!

{ "Value": "v=DMARC1; p=reject; pct=100" }

Responder3

Faltam escapes em algumas aspas e barras invertidas no final. Seria mais fácil gerenciar as cotações se você usasse aspas simples na string do documento JSON.

Parece que você deseja inserir valores da variável shell em um documento JSON. Você faz isso com mais segurança com jq:

$ domain=my.domain.example.com
$ domainName=some-domain-name
$ JSON=$( jq -c -n --arg domain "$domain" --arg name "$domainName" '
{ "Comment": "Updating TXT record in \($domain)",
  "Changes": [ {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "_dmarc.\($name)", "Type": "TXT", "TTL": 3600,
        "ResourceRecords": [ { "Value": "\"v=DMARC1; p=reject; pct=100\"" } ]
      } } ] }' )

O jqcomando é usado aqui para inserir os valores das duas variáveis ​​​​do shell domainem domainNameum documento JSON in-line. As duas variáveis ​​são usadas na linha de comando para inicializar duas jqvariáveis ​​internas $domaine $name, respectivamente. Estes são referenciados pelo documento JSON, nas strings onde devem ser inseridos.

Fazer isso dessa maneira garante que todos os caracteres que precisam de escape especial sejam escapados adequadamente para inclusão nas strings JSON do documento.

Observe que deixei as aspas duplas incorporadas nessa string no final, pois não sei se são obrigatórias ou não. Um analisador JSON decodificaria corretamente as aspas escapadas ao ler os dados.

informação relacionada