
Ich möchte JSON-Daten per HTTPIE übermitteln.
Wenn ich doppelte Anführungszeichen verwende und die Anführungszeichen um den Schlüssel herum maskiere, funktioniert es.
json="[ \
{ \
\"count\": 3 \
} \
]"
echo $json
[ { "Anzahl": 3 } ]
Aber ich will nicht fliehen. Folgendes lässt sich einfacher kopieren und einfügen, funktioniert aber nicht.
json='[ \
{ \
"count": 3 \
} \
]'
echo $json
[ \ { \ "Anzahl": 3 \ } \ ]
Ist es also möglich, die Anführungszeichen rund um den JSON-Schlüssel nicht zu maskieren, um das Kopieren von irgendwoher und Einfügen zu erleichtern?
Antwort1
In
var="foo\
bar"
Die Sequenz \<newline>
ist innerhalb von doppelten Anführungszeichen etwas Besonderes, innerhalb von einfachen Anführungszeichen jedoch nicht.ENTFERNT, $var
enthält also foobar
.
Wenn Sie Folgendes tun:
echo $json
Sie verwenden den Operator „Split+Glob“ (impliziter Operator, der aufgerufen wird, wenn Sie vergessen, eine Erweiterung in Anführungszeichen zu setzen). Das heißt, der Inhalt $json
wird in die in enthaltenen Zeichen aufgeteilt $IFS
und für jedes Wort wird ein Dateiname generiert (auch als „Globbing“ bezeichnet).
Der Standardwert von $IFS
enthält Leerzeichen, Tabulatoren und Zeilenumbrüche (und Leerzeichen, Tabulatoren und Zeilenumbrüche werden beim Aufteilen auch besonders behandelt, indem jede Folge davon als eins zählt und führende und nachfolgende ignoriert werden). So zum Beispiel in:
var=' foo *
bar'
echo $var
$var
wird zunächst in aufgeteilt foo
, *
und bar
(dieTeiltTeil) und *
wird auf die Liste der nicht versteckten Dateien im aktuellen Verzeichnis erweitert (derGlobusTeil).
Wenn Sie den Inhalt unverändert anzeigen möchten (beachten Sie jedoch, dass viele echo
Implementierungen den Inhalt verstümmeln können), schreiben Sie:
$ echo "$json"
[ { "count": 3 } ]
Wenn Sie nun den Abstand komprimieren möchten, können Sie den Operator „Split+Glob“ möglicherweise zu Ihrem Vorteil nutzen.
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
echo
gibt seine Argumente durch Leerzeichen getrennt aus, sodass jede Folge von Leerzeichen, Tabulatoren oder Zeilenumbruchzeichen tatsächlich durch ein einzelnes Leerzeichen ersetzt wird (außer den führenden und nachfolgenden, die entfernt werden, und echo
fügt am Ende ein Zeilenumbruchzeichen hinzu). Sie erhalten also:
[ { "count": 3 } ]
Dabei wird jedoch nicht unterschieden, ob die Leerzeichen in Anführungszeichen stehen oder nicht, sodass sich die Bedeutung der JSON-Daten ändern kann ( "foo bar"
würde "foo bar"
beispielsweise in Folgendes umgewandelt werden).
Wenn Sie die Sequenz zum Escapen (Entfernen) der Zeilenumbruchzeichen verwenden möchten \<newline>
, die anderen Leerzeichen aber ansonsten beibehalten möchten, während die Anführungszeichen nicht escapet werden müssen, können Sie ein folgendes Dokument verwenden:
json=$(cat <<EOF
[\
{\
"count": 3\
}\
]
EOF
)
echo "$json"
Das würde ergeben:
[ { "count": 3 } ]
(Die Zeilenumbrüche wurden entfernt (Sie hätten einige davon beibehalten können, indem Sie ihnen keinen Backslash vorangestellt hätten), die anderen Leerzeichen wurden jedoch unverändert gelassen.)
Antwort2
Um Zeilen in Anführungszeichen fortzusetzen, sind Backslashs nicht erforderlich. Im zweiten Beispiel sind die Backslashs tatsächlich schädlich, da sie in einfachen Anführungszeichen beibehalten werden, was die Zeichenfolge syntaktisch ungültig macht. Entfernen Sie einfach die Backslashs, dann funktioniert es.