2017-02-17 8 views
0

jqを使ってjsonファイルを作成して更新するシェルスクリプトを作成しました。 jsonファイルを作成するにはうまくいきます。私は、コマンドにjson with jq with shell script

#!/bin/sh 
OPER=$1 
FILE_PATH=$2 
DATE_TIME=`date +%Y-%m-%d:%H:%M:%S` 
DATE=`date +%Y-%m-%d` 
CSV=$3 
STEP=$4 
STATUS=$5 
CODE=$6 
MESSAGE=$7 

if [ "$#" -eq 7 ]; then 
    if [ "$OPER" == "create" ]; then 
     # echo "FILE_PATH: $FILE_PATH - CSV: $CSV - STEP: $STEP - STATUS: $STATUS - CODE: $CODE - MESSAGE: $MESSAGE" 
     REPORT="{\"date\": \"$DATE\", \"csv\": \"$CSV\", \"messages\": [{ \"timestamp\": \"$DATE_TIME\", \"step\": \"$STEP\", \"status\": \"$STATUS\", \"code\": \"$CODE\", \"message\": \"$MESSAGE\" }] }" 
     echo ${REPORT} | jq . > $FILE_PATH 
    elif [ "$OPER" == "update" ]; then 
       echo "FILE_PATH: $FILE_PATH - CSV: $CSV - STEP: $STEP - STATUS: $STATUS - CODE: $CODE - MESSAGE: $MESSAGE" 
     REPORT="{\"timestamp\": \"$DATE_TIME\", \"step\": \"$STEP\", \"status\": \"$STATUS\", \"code\": \"$CODE\", \"message\": \"$MESSAGE\"}" 
     echo "REPORTTTTT: "$REPORT 
     REPORT="jq '.messages[.messages| length] |= . + $REPORT' $FILE_PATH" 
     #echo $REPORT 
     echo `jq '.messages[.messages| length] |= . + $REPORT' $FILE_PATH` > $FILE_PATH 
    else 
     echo "operation not recognized: $OPER" 
    fi 
else 
     echo "wrong parameters." 
fi 
jq . $FILE_PATH 

をJQするしかし、私はエラーを取得していますJSONファイルを更新するには、引数として渡される変数を持っています。 My $ REPORT変数が正しいです。コートは正しいです。私は|= . +の代わりに別のjq引数を使う必要があると思います。私はプレーンテキストでそのコマンドを使用し、それは働いた。しかし、REPORT変数を動的に作成すると、エラーがスローされます。

ヒント?ここで

REPORTTTTT: {"timestamp": "2017-02-17:12:11:11", "step": "2", "status": "OK", "code": "34", "message": "message 34 file.xml"} 
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1: 
'.messages[.messages| 
jq: 1 compile error 

jq: error: REPORT/0 is not defined at <top-level>, line 1: 
.messages[.messages| length] |= . + $REPORT          
jq: 1 compile error 

おかげ

は、コマンドラインでの例>>

$ jq . file.json 
{ 
    "date": "2017-02-17", 
    "csv": "file.csv", 
    "messages": [ 
    { 
     "timestamp": "2017-02-17:12:31:21", 
     "step": "1", 
     "status": "OK", 
     "code": "33", 
     "message": "message 33" 
    } 
    ] 
} 
$ export REPORT="{\"timestamp\": \"2017-02-17:11:51:14\", \"step\": \"2\", \"status\": \"OK\", \"code\": \"34\", \"message\": \"message 34 file.xml\"}" 
$ echo $REPORT 
{"timestamp": "2017-02-17:11:51:14", "step": "2", "status": "OK", "code": "34", "message": "message 34 file.xml"} 
$ jq '.messages[.messages| length] |= . + $REPORT' file.json 
jq: error: REPORT/0 is not defined at <top-level>, line 1: 
.messages[.messages| length] |= . + $REPORT          
jq: 1 compile error 
+1

どのコマンドが失敗したかを示す最小の例を作成しますか?現在の情報は読み込めません。 – Inian

+1

https://stackoverflow.com/help/mcve – hek2mgl

答えて

1

以降jq-1.5からサポート--argjsonフラグを使用してjson引数として引数を渡す$REPORTある

--argjson name JSON-text:  
This option passes a JSON-encoded value to the jq program as a predefined variable. 

Chあなたの行に、

jq --argjson args "$REPORT" '.data.messages += [$args]' file 
0

ありがとう@Inian。私は少し変更しましたが、ここでは解決策です。

if [ "$#" -eq 7 ]; then 
    if [ "$OPER" == "update" ]; then 
     echo "update Json" 
       echo "FILE_PATH: $FILE_PATH - CSV: $CSV - STEP: $STEP - STATUS: $STATUS - CODE: $CODE - MESSAGE: $MESSAGE" 
     REPORT="{\"timestamp\": \"$DATE_TIME\", \"step\": \"$STEP\", \"status\": \"$STATUS\", \"code\": \"$CODE\", \"message\": \"$MESSAGE\"}" 
     echo "REPORTTTTT: "$REPORT 
     echo `jq --argjson args "$REPORT" '.data.messages += [$args]' $FILE_PATH` > $FILE_PATH 
    else 
     echo "operation not recognized: $OPER" 
    fi 
else 
     echo "wrong parameters." 
fi 
+0

これは私の答えに何も追加していません。これを取り除き、私の答えが受け入れられたことをマークして解決したことを確認してください – Inian

+0

なぜ 'jp'を使ってJSON *と*を生成して、' REPORT'を手動で定義していますか? – chepner

0

手動でJSONを生成しないでください。 jqとしましょう。

$ foo='"hi" he said' 
$ json="{ \"text\": \"$foo\" }" 
$ echo "$json" 
{ "text": ""hi" he said" } # Wrong: should be { "text": "\"hi\" he said" } 

さらに、jqは、日付と時刻を生成することができます:あなたはJSONに追加する値は、あなただけのシェルで、文字列の補間を実行している場合は発生しませんこれは、適切に引用符で囲む必要がある場合、これは重要です文字列; date(2回)を実行する必要はありません。

#!/bin/sh 

if [ $# -eq 7 ]; then 
    printf "Wrong number of parameters: %d\n" "$#" >&2 
    exit 1 
fi 

oper=$1 file_path=$2 

# Generate the new message using arguments 3-7 
new_message=$(
    jq -n --arg csv "$3" --arg step "$4" \ 
     --arg status "$5" --arg code "$6" \ 
     --arg message "$7" '{ 
    timestamp: now|strftime("%F:%T"), 
    csv: $csv, step: $step, status: $status, code: $code, message: $message}' 
) 

case $oper in 
    create) 
    jq -n --argjson new_msg "$new_message" --arg csv "$3" '{ 
     date: now|strftime("%F"), 
     csv: $csv, 
     messages: [ $new_msg ] 
    }' > "$file_path" 
    ;; 

    update) 
    jq --argjson new_msg "$new_message" \ 
     '.messages += [ $new_msg ]' \ 
     "$file_path" > "$file_path.tmp" && mv "$file_path.tmp" "$file_path" ;; 

    *) printf 'operation not recognized: %s\n' "$oper" >&2 
    exit 1 ;; 
esac 
jq '.' "$file_path"