2016-08-06 2 views
-3

Meine BASH Funktion:

json_format() { 
     echo '{ 
       "question": "';echo "$1";echo '",' 
} 

für:

json_format ${questions[$Q_counter]} 

kehrt zurück:

{ 
       "question": " 
VM 
", 

Statt erwartet JSON-Format und Zeichenkette:

{ 
    "question": "VM CPU is at 100% and you'r jumpbox creds be broken! What do you do?", 

Die Zeichenfolge scheint an der Leerstelle nach dem ersten Wort "VM" abgeschnitten zu sein, und die Formatierung ist mit diesen Echobefehlen etwas aus. Wie kann ich meine Funktion korrigieren? Vielen Dank!

+0

Schauen Sie sich bitte [editing-help] (http://stackoverflow.com/editing-help) an. – Cyrus

+1

Lesen Sie zuerst die [echo' Handbuchseite] (http://man7.org/linux/man-pages/man1/echo.1.html). Dann lies [die Bash-Handbuchseite] (http://man7.org/linux/man-pages/man1/bash.1.html) und denke über die Argumente nach, die du an die Funktion übergibst. –

+0

BTW, was ist dein eigentliches Ziel hier? Wenn ein gültiger JSON generiert werden soll, der beliebige Strings enthält, gibt es einen ** viel ** besseren Ansatz. –

Antwort

1

Der ideale Weg, JSON von Shell zu erzeugen, ist ein Werkzeug wie jq zu verwenden, die tatsächlich das Format versteht:

json_format() { 
    jq -n --arg q "$1" '{"question": $q}' 
} 

... oder, wenn Sie einen Python-Interpreter haben, kann die built-in json module auch sein verwendet:

json_format() { 
    python -c 'import sys, json; print json.dumps({"question": sys.argv[1]})' "$1" 
} 

Wenn Sie eines dieser Tools nicht haben, aber mindestens eine best-Effort-Versuch zu entkommen:

json_format() { 
    local s=$1 
    s=${s//'\'/'\\'} # replace \ with \\ 
    s=${s//'"'/'\"'} # replace " with \" 
    s=${s//$'\n'/'\n'} # replace newline literals with \n 
    printf '{\n\t"question": "%s"\n}\n' "$s" 
} 

... oder einen Wert zu einem Zeitpunkt, zu verarbeiten:

json_format() { 
    local s=$1 
    s=${s//'\'/'\\'} # replace \ with \\ 
    s=${s//'"'/'\"'} # replace " with \" 
    s=${s//$'\n'/'\n'} # replace newline literals with \n 
    printf '%s\n' "$s" 
} 

... einzeln aufgerufen für jeden String formatiert werden, wie in:

cat <<EOF 
{ 
    "question": "$(json_format "$question")", 
    "image": "$(json_format "$image_url")", 
    "choices": [ ], 
    "correct": [ "$(json_format "$answer")" ], 
    "explanation": "$(json_format "$explanation")" 
} 
EOF 

Dies funktioniert korrekt mit Fällen, für die naive Ansätze gültig sind, die tatsächlich kein gültiger JSON sind. Betrachten wir zum Beispiel:

# naive string substitution will fail here because it won't escape double quotes 
json_format 'How do you spell "hello" in Spanish?' 

oder

# naive string substitution will fail here because it won't escape the newline 
json_format $'This question has\ntwo lines' 

oder

# naive string substitution will fail here because it won't escape the backslash 
json_format 'This question ends in a backslash: \' 

Hinweis, in allen oben genannten, die zitierte - die dafür sorgt, dass die Zeichenfolge als übergeben wird ein einziges Argument.

+0

jq ist ein großartiger Vorschlag, aber die Anforderungen sind zu hoch für meine Situation. [Flex, bison, gcc, make, autotools, ruby, oniguruma und git] Ich habe keine davon in meiner Bereitstellung. – mL7i

+0

Das sind Werkzeuge, die Sie brauchen * kompiliere * 'jq', nicht * benutze * eine Kopie von' jq' bereits kompiliert (gut, abhängig davon, ob du statische oder dynamische Links zu oniguruma machst) .Das heißt, hast du einen Python-Interpreter? Ein Python-Einzeiler kann auch für den Zweck verwendet werden –

+0

... bearbeitet, um einen solchen einzeiligen –