大きなjsonオブジェクトの変数でjson文字列のbash変数を置き換える

大きなjsonオブジェクトの変数でjson文字列のbash変数を置き換える

bash 変数で AWS cli を正常に動作させることはできません。 AWS cliコマンドはJSON文字列をパラメータとして受け入れます。しかし、このjson文字列で私が使用する変数$SCHEMA_DEFINITION自体はJSON文字列です。何らかの理由で$SCHEMA_DEFINITIONJSONから二重引用符が削除され、無効になりました。これらの参照を保存して有効なAWSコマンドを生成するにはどうすればよいですか?

aws glue create-schema --cli-input-json '{"RegistryId": {"RegistryName": "hxp-schema-registry"},"SchemaName": "'$modelClassName'","DataFormat": "AVRO","Compatibility": "FULL_ALL","SchemaDefinition": "'"$SCHEMA_DEFINITION"'"}'

エラーが発生します。

An error occurred (InvalidInputException) when calling the CreateSchema operation: Schema definition of AVRO data format is invalid: Unexpected character ('n' (code 110)): was expecting double-quote to start field name
 at [Source: (String)"{name:hello}"

変数を設定する方法は次のとおりです。SCHEMA_DEFINITION={"name":"Hello"}

答え1

生成するJSONには、キー値でJSON文字列でエンコードされたJSONオブジェクトが含まれている必要がありますSchemaDefinition。また、modelClassNameシェル変数の値をキー値として含めたいと思いますSchemaName

jq以下を使用してJSONを作成できます。

json=$(
    jq -n -c \
        --arg SchemaName "$modelClassName" \
        --arg SchemaDefinition '{"name": "Hello"}' \
        '{"RegistryId":{"RegistryName":"hxp-schema-registry"},"DataFormat":"AVRO","Compatibility":"FULL_ALL"} + $ARGS.named'
)

または、読みやすくするために

json=$(
    jq -n -c \
        --arg SchemaName "$modelClassName" \
        --arg SchemaDefinition '{"name": "Hello"}' '
    {
      "RegistryId": {
        "RegistryName": "hxp-schema-registry"
      },
      "DataFormat": "AVRO",
      "Compatibility": "FULL_ALL"
    } + $ARGS.named'
)

でも、

schema_json=$(
    jq -n -c --arg name 'hello' '$ARGS.named'
)

json=$(
    jq -n -c \
        --arg SchemaName "$modelClassName" \
        --arg SchemaDefinition "$schema_json" '
    {
      "RegistryId": {
        "RegistryName": "hxp-schema-registry"
      },
      "DataFormat": "AVRO",
      "Compatibility": "FULL_ALL"
    } + $ARGS.named'
)

これは、スキーマ定義のJSONオブジェクトとモデルクラス名をJSON文字列に正しくエンコードし、それをJSONドキュメントの適切な場所に挿入します。

次に、コマンドを呼び出します。

aws glue create-schema --cli-input-json "$json"

答え2

シェルはあなたの提案を食べています。引用符はシェルに特別なので、スペースなどの他の特殊文字を保護する必要があります。

$ var=aaa bb cc
bash: bb: command not found
terdon@tpad ~ $ var="aaa bb cc"
terdon@tpad ~ $ echo "$var"
aaa bb cc

したがって、あなたの場合、シェルは値を厳密に保護すると考えているため、値を変数値の一部として保存しません。

$ SCHEMA_DEFINITION={"name":"Hello"}
$ echo "$SCHEMA_DEFINITION"
{name:Hello}

でも心配しないでください。簡単な解決策があります!変数定義の周囲に単一引用符を使用できます。

$ SCHEMA_DEFINITION='{"name":"Hello"}'
$ echo "$SCHEMA_DEFINITION"
{"name":"Hello"}

または、引用符をエスケープすることもできます。

$ SCHEMA_DEFINITION={\"name\":\"Hello\"}
$ echo "$SCHEMA_DEFINITION"
{"name":"Hello"}

printfまたは、組み込みコマンドを使用することもできます。

$ printf -v SCHEMA_DEFINITION '{"%s":"%s"}' "name" "Hello"
$ echo "$SCHEMA_DEFINITION"
{"name":"Hello"}

またはあなたは使用することができますjo(1)便利:

SCHEMA_DEFINITION=$(jo name=hello)

まず、すべてを変数として構築することをお勧めします。

schema_definition='{"name":"Hello"}'
modelClassName='"thisModel"'
json_string='{"RegistryId": {"RegistryName": "hxp-schema-registry"},"SchemaName":'
json_string="$json_string $modelClassName"
json_string="$json_string"' "DataFormat": "AVRO","Compatibility": "FULL_ALL","SchemaDefinition": '"$schema_definition"

結果:

$ echo "$json_string"
{"RegistryId": {"RegistryName": "hxp-schema-registry"},"SchemaName": "thisModel" "DataFormat": "AVRO","Compatibility": "FULL_ALL","SchemaDefinition": {"name":"Hello"}

これで、次のことができます。

aws glue create-schema --cli-input-json "$json_string"

答え3

Terdonが正しいです。 json変数が正しく設定されていませんが、コマンドに誤って渡しています。

あなたは以下を通過しています:

{
    "RegistryId": {
        "RegistryName": "hxp-schema-registry"
    },
    "SchemaName": "'$modelClassName'",
    "DataFormat": "AVRO",
    "Compatibility": "FULL_ALL",
    "SchemaDefinition": "'"$SCHEMA_DEFINITION"'"
}

これは次のように拡張されます。

{
    "RegistryId": {
        "RegistryName": "hxp-schema-registry"
    },
    "SchemaName": "'$modelClassName'",
    "DataFormat": "AVRO",
    "Compatibility": "FULL_ALL",
    "SchemaDefinition": "{"name":"Hello"}"
}

注意してください"{"name":"Hello"}"

これについてはheredocを使用することをお勧めしますが、どちらにしても{}

read -rd json <<EOF
{
    "RegistryId": {
        "RegistryName": "hxp-schema-registry"
    },
    "SchemaName": "$modelClassName",
    "DataFormat": "AVRO",
    "Compatibility": "FULL_ALL",
    "SchemaDefinition": $SCHEMA_DEFINITION
}
EOF

またはjo(1)を使用してください:

json=$(jo RegistryId=$(jo RegistryName=hxp-schema-registry) \
SchemaName=$modelClassName \
DataFormat=AVRO \
Compatibility=FULL_ALL \
SchemaDefinition=$SCHEMA_DEFINITION)

その後、変数を使用してコマンドを呼び出すことができます。

aws glue create-schema --cli-input-json "$json"

私もお勧めしますhttps://jsonlint.com/これらの問題が発生した場合は、json入力を確認してください。

関連情報