
다음 JSON 데이터가 있습니다.
{ "이름": "응답 없음", "이메일": "[이메일 보호됨]", "ID": 5930, "세부 사항": { "message": "당신의 이름: John Doe\n이메일:[이메일 보호됨]\n제목: 이 문제에 대한 도움이 필요합니다\n설명: 설명서 다운로드를 찾을 수 있지만 Windows 또는 Mac용 무료 업데이트만 찾을 수 있습니다. 제가 Chrome 노트북과 Moto 스마트폰을 가지고 있으니 도와주실 수 있나요? 감사해요. 존 도우" } }
최상위 이름 및 이메일 필드는 자동 이메일에서 제공되므로 관련이 없습니다. 필요한 정보는 John Doe의 정보와 관련된 메시지 필드와 ID 필드에 있습니다.
어쨌든, 필터링해야 할 사항과 이를 다음 순서에 따라 새 파일에 저장하는 방법은 다음과 같습니다.
- 이름:텍스트에 관계없이 해당 변수 다음 줄을 읽어야 합니다.
- 이메일:같은 상기와
- 주제:같은 상기와
- 설명하다:같은 상기와
- 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: ...
메시지의 일부가 한 줄이고 헤더가 표준 형식이라고 가정합니다(그렇지 마십시오 " 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