jq filtering - Невозможно индексировать массив строкой «Score» - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь найти имя человека, у которого есть предмет и его оценка.Но я получаю индексный массив.Эта проблема отличается от других вопросов, задаваемых в Stackoverflow, поскольку он выдает ошибку для параметра, который находится не в [], а в {}

jq -r '.[] | select(.result."*value*".Score.English) | {Name: .result."*value*".name, Subject: .result."*value*".Score.English} | @text' test.txt | sed 's/^{\|}$//g; s/,/\n/'

INPUT JSON FILE

[{
    "host": "testserver",
    "hostclass": "Unknown",
    "result": {
        "*value*": [
            {
                "sessionId": "000001",
                "name": "ABC",
                "Age": "21",
                "Score": {
                    "English": "A+",
                    "Mathematics": "B-",
                    "String Theory": "C+"
                }
            },
            {
                "sessionId": "000001",
                "name": "CDE",
                "Age": "21",
                "Score": {
                    "English": "A-",
                    "German": "B-",
                    "French": "C+"
                }
            },
            {
                "sessionId": "000001",
                "name": "EFG",
                "Age": "21",
                "Score": {
                }
            },
            {
                "sessionId": "000001",
                "name": "XYZ",
                "Age": "21"
            }]
   }
}]

OUTPUT:

Name: ABC
Subject : A+
Name: CDE
Subject : A-

ОШИБКА:

jq: error (at test.txt:39): Cannot index array with string "Score"

как я могу исправить эту ошибку?

Ответы [ 3 ]

1 голос
/ 07 мая 2019
  1. Вам нужно расширить массивы для доступа к элементам в них,
  2. Вам вообще не нужен sed.
$ jq -r '.[].result."*value*"[] | select(.Score.English) | "Name: \(.name)", "Subject: \(.Score.English)"' file
Name: ABC
Subject: A+
Name: CDE
Subject: A-
0 голосов
/ 09 мая 2019

вот альтернативное решение, использующее Unix-утилиту на основе пешеходного пути jtc:

Если у вас есть такой нерегулярный JSON и вы хотите, чтобы толькоте name s, которые будут показаны, которые имеют только записи одного и того же [Score][English], тогда такой запрос будет выглядеть так:

bash $ <file.json jtc -x'<name>l:[-1][Score][English]' -y'[-2][name]' -y'[-1][English]' -l
"name": "ABC"
"English": "A+"
"name": "CDE"
"English": "A-"
bash $ 

РЕДАКТИРОВАТЬ: если вместо "English" требуется "Subject", передайтевывод в sed:

... | sed -e 's/^"English/"Subject/g'

PS> Раскрытие информации: я создатель инструмента jtc

0 голосов
/ 07 мая 2019

EFG Оценка имеет длину 0, что, вероятно, не поможет:

"sessionId": "000001",
"name": "EFG",
"Age": "21",
"Score": {}

Поэтому он задыхается при попытке оценить:

Subject: .result."*value*".Score.English 
...