¿Cómo escapo del punto y coma en una cadena con Bash?

¿Cómo escapo del punto y coma en una cadena con Bash?

Obtuve la cadena JSON a continuación que uso para alimentar el aws route53 change-resource-record-setscomando para actualizar un registro DMARC actual. Como puede ver, el valor TXT contiene ;.

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\"" } ] } } ] }"

Cuando echo $JSON, en lugar de toda la cadena JSON, obtuve el siguiente resultado. Parece que el análisis se detiene tan pronto como llega ;.

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

He probado varias formas de escapar del punto y coma, como usar \\;y \";\"sin suerte. ¿Qué hice mal aquí?

Respuesta1

Simplemente use una combinación de comillas simples y dobles y entonces no se verá tan desordenado y será más fácil trabajar con él:

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" } ] } } ] }'

Éste funciona. Ejemplo:

$ 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"
          }
        ]
      }
    }
  ]
}
$

Respuesta2

Resulta que el problema aquí no es escapar del punto y coma, sino del espacio final después del punto y coma. Después de que cambié la cadena a algo como esto

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

¡La cadena ahora hace eco correctamente!

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

Respuesta3

Le faltan escapes en algunas comillas y barras invertidas al final. Sería más fácil administrar las citas si utiliza comillas simples alrededor de la cadena del documento JSON.

Parece que desea insertar valores de la variable de shell en un documento JSON. Lo haces más seguro con 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\"" } ]
      } } ] }' )

El jqcomando se usa aquí para insertar los valores de las dos variables del shell domainen domainNameun documento JSON en línea. Las dos variables se utilizan en la línea de comando para inicializar dos jqvariables internas $domainy $name, respectivamente. Estos están referenciados por el documento JSON, en las cadenas donde se supone que deben insertarse.

Hacerlo de esta manera garantiza que cualquier carácter que necesite un escape especial tenga un escape adecuado para su inclusión en las cadenas JSON del documento.

Tenga en cuenta que dejé las comillas dobles incrustadas en esa cadena al final, ya que no sé si son obligatorias o no. Un analizador JSON decodificaría correctamente las comillas escapadas cuando lea los datos.

información relacionada