¿Es posible no escapar de las comillas dobles y obtener el formato json correcto?

¿Es posible no escapar de las comillas dobles y obtener el formato json correcto?

Quiero enviar datos json usando httpie.

Si uso comillas dobles y escapo de las comillas dobles que rodean la clave, funciona.

json="[ \
    { \
        \"count\": 3 \
    } \
]"

echo $json

[ { "cuenta": 3 } ]

Pero no quiero escapar. Lo siguiente es más fácil de copiar y pegar, pero no funciona.

json='[ \
    { \
        "count": 3 \
    } \
]'

echo $json

[ \ { \ "cuenta": 3 \ } \ ]

Entonces, ¿es posible no escapar de las comillas dobles que rodean la clave json, hacer que sea más fácil copiar desde algún lugar y pegar?

Respuesta1

En

var="foo\
bar"

La secuencia \<newline>es especial entre comillas dobles, pero no entre comillas simples y esremoto, por lo que $varcontiene foobar.

Cuando estás haciendo:

echo $json

Estás utilizando el operador split+glob (operador implícito que se invoca cuando olvidas citar una expansión), es decir, el contenido de $jsonse divide en los caracteres $IFSy cada palabra está sujeta a la generación de nombres de archivo (también conocido como globbing).

El valor predeterminado de $IFScontiene espacio, tabulación y nueva línea (y el espacio, la tabulación y la nueva línea también reciben un tratamiento especial con respecto a la división, ya que cualquier secuencia de ellos cuenta como uno y las iniciales y finales se ignoran). Así por ejemplo en:

var='  foo  *
bar'

echo $var

$varprimero se divide en foo, *y bar(eldividirparte) y *se expande a la lista de archivos no ocultos en el directorio actual (elgloboparte).

Si desea mostrar el contenido tal como está (pero tenga en cuenta que muchas echoimplementaciones pueden alterar el contenido), escribiría:

$ echo "$json"
[     {         "count": 3     } ]

Ahora, si su intención es comprimir el espaciado, tal vez pueda utilizar el operador split+glob a su favor.

json='
  [
    {
      "count": 3
    }
  ]'

unset -v IFS # make sure we get a default splitting behaviour.
             # an unset -v IFS is equivalent to IFS=$' \t\n'
set -o noglob # disable the glob part

echo $json # use the split+glob operator

echogenera sus argumentos separados por espacios, por lo que cada secuencia de espacio, tabulación o carácter de nueva línea será reemplazada por un solo carácter de espacio (excepto los iniciales y finales que se eliminarán y echoagregarán un carácter de nueva línea al final). Entonces obtendrás:

[ { "count": 3 } ]

En cualquier caso, eso no discriminará si los espacios en blanco están entre comillas o no, por lo que puede cambiar el significado de los datos json ( "foo bar"se transformarían, "foo bar"por ejemplo).

Si desea usar la \<newline>secuencia para escapar (eliminar) los caracteres de nueva línea pero, de lo contrario, mantener los otros caracteres en blanco sin tener que escapar de las comillas dobles, puede usar un documento aquí:

json=$(cat <<EOF
  [\
    {\
      "count": 3\
    }\
  ]
EOF
)
echo "$json"

Lo que daría:

  [    {      "count": 3    }  ]

(Las nuevas líneas se han eliminado (podría haber elegido conservar algunas de ellas sin anteponerles una barra invertida) pero los demás caracteres en blanco se han dejado intactos).

Respuesta2

No es necesario utilizar barras invertidas para continuar líneas entre comillas. En el segundo ejemplo, las barras invertidas son activamente dañinas, porque entre comillas simples se mantendrán como tales, lo que hará que la cadena sea sintácticamente inválida. Simplemente elimine las barras invertidas y funcionará.

información relacionada