次のJSONデータがあります。
{ 「名前」:「応答なし」、 "メール": "[Eメール保護]」、 「ID」:5930、 「詳細」: { "message": "あなたの名前: John Doe\nEメール:[Eメール保護]\nタイトル:この問題についてのヘルプが必要です\n説明:ドキュメントのダウンロードが見つかりますが、WindowsまたはMac用の無料アップデートのみを見つけることができます。私はChromeノートパソコンとMotoスマートフォンを持っていますが、助けることができますか?ありがとうございます。ジョン・ドウ」 } }
最上位の名前と電子メールフィールドは自動電子メールで提供されるため、関連性はありません。必要な情報は、John Doeの情報に関連するメッセージフィールドとIDフィールドにあります。
とにかく、フィルタリングする必要があるものと、次の順序で新しいファイルに保存する方法は次のとおりです。
- 名前:テキストに関係なく、対応する変数の次の行を読む必要があります。
- Eメール:同じ上記と
- トピック:同じ上記と
- 説明する:同じ上記と
- ID:同じ上記と
したがって、引用符、改行文字を削除し、bashを介してこれらの特定の文字列を変数に割り当て、この文字列の後に続く内容を読む必要があります。
何かを思い出すことができましたが、次のJSON出力では機能しません。 (テキストファイルの形式が正しい場合にのみ機能します。)
while IFS=''
do case "$line" in
"Name:"*) uservar="${line#*: }" ;;
"Email:"*) emailvar="${line#*: }" ;;
"Subject:"*) subject="${line#*: }" ;;
"Message:"*) message="${line#*: }" ;;
"ID:"*) ticketidvar="${line#*: }" ;;
esac
done <<-EOF
$(pbpaste)
EOF
答え1
これはDescription: ...
、メッセージの一部が1行で、ヘッダーが標準形式であると仮定します(そうではありません" subJECT :hey"
)。
シェルに適した方法で出力(一重引用符を含む)をエスケープするjq
形式仕様を使用します。@sh
ありがとうございました @Stéphane Chazelasに感謝します。
parse_json(){
jq=$(jq -r '[.Email,.ID,(.details.message | split("\n")) | @sh] | join(" ")' -- "$1")
eval "set -- $jq"
email=$1; shift
id=$1; shift
for l; do
case $l in
"Your name: "*) name="${l#*: }";;
"Subject: "*) subject="${l#*: }";;
"Description: "*) description="${l#*: }";;
# remove the following line if you want the .Email from json instead
"Email: "*) email="${l#*: }";;
esac
done
echo "id={$id}"
echo "name={$name}"
echo "email={$email}"
echo "subject={$subject}"
echo "description={$description}"
}
fz:/tmp% parse_json a.json
id={5930}
name={john doe}
email={[email protected]}
subject={I need help with this}
description={I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe
上記は、case ... esac
タイトルと同じ名前の変数を生成し、英数字以外の文字を下線で置き換える方法で置き換えることができます。これは${var//pat/repl}
、代替(bash
、、zsh
)をサポートするksh93
シェルでのみ機能します。
parse_json(){
jq=$(jq -r '[.Email,.ID,(.details.message | split("\n")) | @sh] | join(" ")' -- "$1")
eval "set -- $jq"
Email=$1; shift
ID=$1; shift
for l; do
v="${l#*: }"; k="${l%%: *}"; eval "${k//[!a-zA-Z0-9]/_}=\$v"
done
}
show_vars(){
for v in ID Your_name Email Subject Description; do
eval "echo \"$v=[\$$v]\""
done
}
fz:/tmp$ parse_json a.json
fz:/tmp$ show_vars
ID=[5930]
Your_name=[john doe]
Email=[[email protected]]
Subject=[I need help with this]
Description=[I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe]
答え2
連想配列を使用できます。
typeset -A field="($(jq -r '
"[ID]=" + (.ID|@sh),
(.details.message|capture("(?m)^(?<t>.*?): (?<v>.*)"; "g")|
"["+(.t|@sh)+"]="+(.v|@sh))' file.json))"
それからあなたのIDはにあり、 ${field[ID]}
タイトルは${field[Subject]}
...にあります。
サンプルでは、typeset -p field
出力は次のようになります。
declare -A fields=(
[Description]="I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe"
[ID]="5930"
[Subject]="I need help with this"
[Email]="[email protected]"
["Your name"]="john doe"
)
答え3
私が正確に理解したかどうかはわかりませんが、の内容から変数を生成することが目的であれば、.details.message
以下を提案します。
.details.message
生モードでの最初の抽出jq
:
jq -r '.details.message' in.json
sed
次に、bashで解析できるように解析します。
解析.sed
/^Your name: / s//uservar="/
/^Email: / s//emailvar="/
/^Subject: / s//subject="/
/^Description: / s//message="/
s/$/"/
これで、次のようにスクリプトからこれを取得できます。
. <(jq -r '.details.message' in.json | sed -f parse.sed)
echo $uservar, $emailvar
出力:
john doe, [email protected]
答え4
必要なのは、デコードされた.details.message
文字列とそれに続くIDを含む行があると仮定します。
jq -r '.details.message, "ID: \(.ID)"' file >outfile
これにより、.details.message
文字列がデコードされ、.ID
プレフィックスが付いた最上位キー値を含む別々の行が追加されますID:
。
指定されたJSON文書に対して、ファイルに次の出力が生成されますoutfile
。
Your name: john doe
Email: [email protected]
Subject: I need help with this
Description: I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe
ID: 5930