약간 변형된 JSON 문자열에서 데이터를 추출해야 하므로 먼저 sed
& 를 통해 전달합니다 awk
. 내가 가진 것은 다음 명령입니다.
`sed 's/},/},\n/g' test.json |awk '/"characater"/ { gsub("\"characater\"", "\"char" ++n "\"", $0) } 1'| jq -r '.frames.frame.lps.lp|.characters[]|[.code_ascii,.confidence]|@tsv'`
다음과 같이 JSON 문자열에서 데이터를 추출합니다.
{"response":{"container":{"id":"41d6efcb-24d6-490d-8880-762255519b5f","timestamp":"2018-Jul-11 19:51:06.461665"},"id":"00000002-0000-0000-0000-000000000015"},"frames":{"frame":{"id":"5583","timestamp":"2016-Nov-30 13:05:27","lps":{"lp":{"licenseplate":"15451BBL","text":"15451BBL","wtext":"15451BBL","confidence":"20","bkcolor":"16777215","color":"16777215","type":"0","ntip":"11","cct_country_short":"","cct_state_short":"","tips":{"tip":{"poly":{"p":{"x":"1094","y":"643"},"p":{"x":"1099","y":"643"},"p":{"x":"1099","y":"667"},"p":{"x":"1094","y":"667"}},"bkcolor":"16777215","color":"0","code":"49","code_ascii":"1","confidence":"97"},"tip":{"poly":{"p":{"x":"1103","y":"642"},"p":{"x":"1113","y":"642"},"p":{"x":"1112","y":"667"},"p":{"x":"1102","y":"667"}},"bkcolor":"16777215","color":"0","code":"53","code_ascii":"5","confidence":"89"},"tip":{"poly":{"p":{"x":"1112","y":"640"},"p":{"x":"1122","y":"640"},"p":{"x":"1122","y":"666"},"p":{"x":"1112","y":"666"}},"bkcolor":"16777215","color":"0","code":"52","code_ascii":"4","confidence":"97"},"tip":{"poly":{"p":{"x":"1123","y":"640"},"p":{"x":"1132","y":"640"},"p":{"x":"1131","y":"665"},"p":{"x":"1123","y":"665"}},"bkcolor":"16777215","color":"0","code":"53","code_ascii":"5","confidence":"97"},"tip":{"poly":{"p":{"x":"1134","y":"640"},"p":{"x":"1139","y":"640"},"p":{"x":"1139","y":"664"},"p":{"x":"1133","y":"664"}},"bkcolor":"16777215","color":"0","code":"49","code_ascii":"1","confidence":"77"},"tip":{"poly":{"p":{"x":"1154","y":"639"},"p":{"x":"1163","y":"639"},"p":{"x":"1163","y":"663"},"p":{"x":"1153","y":"663"}},"bkcolor":"16777215","color":"0","code":"66","code_ascii":"B","confidence":"97"},"tip":{"poly":{"p":{"x":"1164","y":"638"},"p":{"x":"1173","y":"638"},"p":{"x":"1173","y":"663"},"p":{"x":"1163","y":"663"}},"bkcolor":"16777215","color":"0","code":"66","code_ascii":"B","confidence":"94"},"tip":{"poly":{"p":{"x":"1191","y":"637"},"p":{"x":"1206","y":"636"},"p":{"x":"1205","y":"660"},"p":{"x":"1190","y":"661"}},"bkcolor":"16777215","color":"0","code":"76","code_ascii":"L","confidence":"34"},"tip":{"poly":{"p":{"x":"1103","y":"655"},"p":{"x":"1111","y":"655"},"p":{"x":"1111","y":"667"},"p":{"x":"1103","y":"667"}},"bkcolor":"16777215","color":"0","code":"74","code_ascii":"J","confidence":"57"},"tip":{"poly":{"p":{"x":"1103","y":"655"},"p":{"x":"1111","y":"655"},"p":{"x":"1111","y":"667"},"p":{"x":"1103","y":"667"}},"bkcolor":"16777215","color":"0","code":"74","code_ascii":"J","confidence":"57"},"tip":{"poly":{"p":{"x":"1176","y":"638"},"p":{"x":"1185","y":"637"},"p":{"x":"1184","y":"661"},"p":{"x":"1175","y":"662"}},"bkcolor":"16777215","color":"0","code":"52","code_ascii":"4","confidence":"7"}},"ncharacter":"8","characters":{"characater":{"poly":{"p":{"x":"1094","y":"643"},"p":{"x":"1099","y":"643"},"p":{"x":"1099","y":"667"},"p":{"x":"1094","y":"667"}},"bkcolor":"16777215","color":"0","code":"49","code_ascii":"1","confidence":"97"},"characater":{"poly":{"p":{"x":"1103","y":"642"},"p":{"x":"1113","y":"642"},"p":{"x":"1112","y":"667"},"p":{"x":"1102","y":"667"}},"bkcolor":"16777215","color":"0","code":"53","code_ascii":"5","confidence":"89"},"characater":{"poly":{"p":{"x":"1112","y":"640"},"p":{"x":"1122","y":"640"},"p":{"x":"1122","y":"666"},"p":{"x":"1112","y":"666"}},"bkcolor":"16777215","color":"0","code":"52","code_ascii":"4","confidence":"97"},"characater":{"poly":{"p":{"x":"1123","y":"640"},"p":{"x":"1132","y":"640"},"p":{"x":"1131","y":"665"},"p":{"x":"1123","y":"665"}},"bkcolor":"16777215","color":"0","code":"53","code_ascii":"5","confidence":"97"},"characater":{"poly":{"p":{"x":"1134","y":"640"},"p":{"x":"1139","y":"640"},"p":{"x":"1139","y":"664"},"p":{"x":"1133","y":"664"}},"bkcolor":"16777215","color":"0","code":"49","code_ascii":"1","confidence":"77"},"characater":{"poly":{"p":{"x":"1154","y":"639"},"p":{"x":"1163","y":"639"},"p":{"x":"1163","y":"663"},"p":{"x":"1153","y":"663"}},"bkcolor":"16777215","color":"0","code":"66","code_ascii":"B","confidence":"97"},"characater":{"poly":{"p":{"x":"1164","y":"638"},"p":{"x":"1173","y":"638"},"p":{"x":"1173","y":"663"},"p":{"x":"1163","y":"663"}},"bkcolor":"16777215","color":"0","code":"66","code_ascii":"B","confidence":"94"},"characater":{"poly":{"p":{"x":"1191","y":"637"},"p":{"x":"1206","y":"636"},"p":{"x":"1205","y":"660"},"p":{"x":"1190","y":"661"}},"bkcolor":"16777215","color":"0","code":"76","code_ascii":"L","confidence":"34"}},"det_time_us":"1072592","poly":{"p":{"x":"1088","y":"642"},"p":{"x":"1210","y":"634"},"p":{"x":"1210","y":"661"},"p":{"x":"1087","y":"669"}}}},"det_time_us":"1720812"}}}
또는 다음 링크에서:https://drive.google.com/file/d/18wCzjMBpw7SIeVFByAGPQiqCBjg_0te3/view?usp=sharing
이제 이것은 훌륭하게 작동하지만 .frames.frame.lps.lp.ncharacter
JSON에서도 추출해야 합니다. 위와 같은 작업을 간단히 수행할 수 있다는 것을 알고 있지만 문자열로 구성된 거대한 JSON 파일을 구문 분석하려면 이러한 명령이 필요하고 문자열은 링크에 표시된 형식이며 매개변수가 표시되어야 cat test.json | jq -r '.frames.frame.lps.lp.ncharacter';
하기 때문에 작동하지 않습니다. .ncharacter
추출된 문자가 있는 줄은 다음과 유사한 출력을 원한다는 것을 의미합니다.
...
X 99
Y 99 previous data formatted in the same way
8
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
6 following data formatted in the same way
Z 99
...
상위 8개는 .ncharacter
매개변수입니다. 나는 시도했다:
sed 's/},/},\n/g' test.json |awk '/"characater"/ { gsub("\"characater\"", "\"char" ++n "\"", $0) } 1'| jq -r '[.frames.frame.lps.lp.ncharacter],.frames.frame.lps.lp|.characters[]|[.code_ascii,.confidence]|@tsv'
하지만 이것이 나에게 주는 jq: error (at <stdin>:102): Cannot index array with string "characters"
이유는 모르겠습니다...
답변1
확인하다:
첫 번째 변종
perl -pe 's/"characater"/"\"char" . (++$n) . "\""/ge' input.json |
jq -r '.frames.frame.lps.lp|.ncharacter,(.characters[]|[.code_ascii,.confidence]|@tsv)'
설명하다
perl -pe 's/"characater"/"\"char" . (++$n) . "\""/ge' input.json
-p
- 각 줄을 반복하고 다음과 같이 인쇄합니다sed
.-e
- 한 줄 프로그램을 입력하는 데 사용할 수 있습니다. 주어 지면-e
Perl은 인수 목록에서 파일 이름을 찾지 않습니다.s///ge
-g
: 전역 교체,e
: 교체 명령의 오른쪽 부분을 표현식으로 평가합니다."\"char" . (++$n) . "\""
- 포인트는 연결에 사용됩니다.
jq -r '.frames.frame.lps.lp|.ncharacter,(.characters[]|[.code_ascii,.confidence]|@tsv)'
.frames.frame.lps.lp|
- 로 작성할 수 있으므로.frames | .frame | .lps | .lp |
다음과 같이 작동합니다. 입력을 받고 모든frames
필드를 선택하여 다른 필터로 파이프한.frame
다음 모든frame
필드를 가져와 다음 필터로 파이프하는 등 -.lps
등이 계속됩니다. 바라보다jq 매뉴얼, 이것관로부분.|.ncharacter,(.characters[]|...)'
-jq 매뉴얼, 이것반점부분: "두 개의 필터가 쉼표로 구분된 경우 동일한 입력이 두 필터 모두에 공급되고 두 필터의 출력 값 스트림이 순서대로 연결됩니다. 먼저 왼쪽 표현식에 의해 생성된 모든 출력, 그런 다음 모두 예를 들어 필터는.foo, .bar
"foo" 필드와 "bar" 필드를 별도의 출력으로 생성합니다.(.characters[]|[.code_ascii,.confidence]|@tsv)
.characters[]
- 괄호는 필터 출력과 별도로 처리되는 출력 에 사용됩니다.ncharacter
.
두 번째 변형- gawk
대신 perl
파일 json
수정을 사용하세요. 이 jq
부분은 첫 번째 변형과 동일합니다.
gawk '{ORS= (RT) ? "\"char" NR "\"" : ""; print}' RS='"characater"' input.json
노트- perl
그리고 명령은 매 프레임마다 블록의 카운터를 재설정 gawk
하지 않습니다 . char
즉, 처음부터 시작 char1
하여 끝까지 증가합니다.
입력하다- 샘플이 3번 복제되었습니다.
산출
8
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
8
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
8
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
답변2
이것은 동일한 주제에 대한 또 다른 질문의 연속입니다. 여기서 주요 문제는 입력에 고유하지 않은 키가 있는 객체가 포함되어 있다는 것입니다. 이는 여전히 유효한 JSON이지만 이후 키가 이전 키를 덮어쓰므로 문서를 구문 분석할 때 데이터가 "손실"됩니다.
이전 질문에 여기에 답변했습니다., 답변에 설명된 다음 명령을 사용하십시오.
$ jq -r -n --stream 'fromstream(1|truncate_stream(5|truncate_stream(inputs)|select(.[0][0] == "characater"))) | [.code_ascii, .confidence] | @tsv' test.json
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
문제는이것문제는 출력이 출력 라인 수 앞에 자체 라인에 있어야 한다는 것입니다. 이러한 이상한 형식의 JSON 문서는 단 하나의 인스턴스가 아니라 전체 세트가 한 줄에 하나씩 있습니다.
다음은 결과를 배열로 수집하여 출력하기 전에 요소 수를 계산하는 위 명령을 수정한 것입니다.
$ jq -r -n --stream '[fromstream(1|truncate_stream(5|truncate_stream(inputs)|select(.[0][0] == "characater"))) | [.code_ascii, .confidence]] | length, (.[]|@tsv)' test.json
8
1 97
5 89
4 97
5 97
1 77
B 97
B 94
L 34
그런 다음 원본 파일의 각 줄에 대해 이 명령을 한 번씩 호출하면 됩니다.
#!/bin/bash
cmd=( jq -r -n --stream '[fromstream(1|truncate_stream(5|truncate_stream(inputs)|select(.[0][0] == "characater"))) | [.code_ascii, .confidence]] | length, (.[]|@tsv)' )
while IFS= read -r json; do
printf '%s\n' "$json" | "${cmd[@]}"
done <test.json