É possível não escapar das aspas duplas e obter o formato json correto?

É possível não escapar das aspas duplas e obter o formato json correto?

Quero enviar dados json usando httpie.

Se eu usar aspas duplas e escapar das aspas duplas ao redor da chave, isso funcionará.

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

echo $json

[ { "contagem": 3 } ]

Mas não quero escapar. O seguinte é mais fácil de copiar e colar, mas não funciona.

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

echo $json

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

Então, é possível não escapar das aspas duplas em torno da chave json, facilitar a cópia de algum lugar e a colagem?

Responder1

Em

var="foo\
bar"

A sequência \<newline>é especial entre aspas duplas, mas não entre aspas simples e éremovido, então $varcontém foobar.

Quando você está fazendo:

echo $json

Você está usando o operador split+glob (operador implícito invocado quando você esquece de citar uma expansão), ou seja, o conteúdo de $jsoné dividido nos caracteres $IFSe cada palavra está sujeita à geração de nome de arquivo (também conhecido como globbing).

O valor padrão de $IFScontém espaço tabulação e nova linha (e espaço, tabulação e nova linha também recebem um tratamento especial em relação à divisão, pois qualquer sequência deles conta como um e as iniciais e finais são ignoradas). Então, por exemplo, em:

var='  foo  *
bar'

echo $var

$varé primeiro dividido em fooe *( barodividirparte) e *é expandido para a lista de arquivos não ocultos no diretório atual (oglobopapel).

Se você quiser exibir o conteúdo como está (mas observe que muitas echoimplementações podem distorcer o conteúdo), você escreveria:

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

Agora, se sua intenção é compactar o espaçamento, talvez você possa usar o operador split+glob a seu 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

echogera seus argumentos separados por espaços para que cada sequência de caracteres de espaço, tabulação ou nova linha seja substituída por um único caractere de espaço (exceto os iniciais e finais que serão removidos e echoadiciona um caractere de nova linha no final). Então você obterá:

[ { "count": 3 } ]

Em qualquer caso, isso não discriminará se os espaços em branco estão entre aspas ou não, portanto pode alterar o significado dos dados json ( "foo bar"seriam transformados em, "foo bar"por exemplo).

Se você quiser usar a \<newline>sequência para escapar (remover) os caracteres de nova linha, mas manter os outros caracteres em branco sem precisar escapar dos caracteres de aspas duplas, você pode usar um documento aqui:

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

O que daria:

  [    {      "count": 3    }  ]

(as novas linhas foram removidas (você poderia ter optado por preservar algumas delas não acrescentando uma barra invertida no início), mas os outros caracteres em branco foram deixados intactos).

Responder2

Não há necessidade de barras invertidas para continuar as linhas entre aspas. No segundo exemplo as barras invertidas são ativamente prejudiciais, pois entre aspas simples elas serão mantidas como tal, tornando a string sintaticamente inválida. Apenas livre-se das barras invertidas e tudo funcionará.

informação relacionada