Próbuję wziąć odpowiedź JSON (z komendy Curl i JQ zainstalowany na moim Linux Comp) z wieloma obiektami i edytuj każdy z pętlą. Problem polega na tym, że nie rozumiem, jak wziąć każdy {} i przekształcić je w oddzielne obiekty. Na przykład moja odpowiedź JSON to:

{
  "Name": "testuser1",
  "Username": "testuser1",
  "Url": "www.test1.com"
}
{
  "Name": "testuser2",
  "Username": "testuser2",
  "Url": "www.test2.com"
}

Idealnie, chcę odnieść się do każdego numeru. Na przykład "echo $ element | JQ '.name [0]" "dla

{
  "Name": "testuser1",
  "Username": "testuser1",
  "Url": "www.test1.com"
}

Kiedy uruchomię polecenie powyżej, otrzymuję następujący błąd.

jq: error (at <stdin>:1): Cannot index string with number

Chciałbym uruchomić pętlę dla każdego obiektu.

0
druffin 1 czerwiec 2018, 22:28

3 odpowiedzi

Najlepsza odpowiedź

Musisz zrobić dwie rzeczy: jeden, użyj opcji -s, dzięki czemu każdy oddzielny obiekt staje się elementem pojedynczej tablicy. Dwa, próbujesz indeksować Name, zamiast uzyskać dostęp do atrybutu Name elementu tablicy.

$ jq -sr '.[].Name' tmp.json
testuser1
testuser2

Jeśli chcesz odnieść się do określonego elementu strumienia, możesz:

$ jq -sr '.[1].Name' tmp.json
testuser2

Z tym (i zakładając, że żadna z twoich nazw nie będzie zawierać Newlines), wygląda odpowiednia pętla

while IFS= read -r name; do
    ...
done < <(jq -sr '.[].Name' tmp.json)
2
chepner 2 czerwiec 2018, 14:50

Aby wybrać tylko imię, musisz wykonać indeksowanie przed , próbując wejść do elementu Name:

jq -rs '.[0].Name'

Natomiast, na pętlę, podejście {x0}} Dane przez @ Chepnera Odpowiedź jest rzeczywiście odpowiedni.

0
Charles Duffy 1 czerwiec 2018, 20:22

JQ jest zorientowany na strumień, więc jeśli chcesz wykonać pewną pracę na każdym obiekcie, może być wystarczające, aby zdefiniować to działanie w JQ i pozwolić JQ uchwycić strumień bez dalszych ADO.

Jeśli z jakiegoś powodu potrzebujesz indeksu każdego elementu w strumieniu, możesz uniknąć opcji -s, jeśli JQ ma inputs (podobnie jak JQ 1.5). (Unikanie opcji -s Zapisuje pamięć.)

Poniżej zakłada, że Twoje JQ ma inputs; ten indeksowanie ma wartość 0; i że JQ jest wywoływany za pomocą opcji -N.

Generowanie indeksu

foreach inputs as $input (-1; .+1; [., $input])

Spowoduje to utworzenie strumienia [indeks, elementu]. Następnie można wyleczyć w dalszych filtrów JQ przy użyciu operatora rur JQ (|).

Wybór elementu I-T z strumienia podmiotów JSON.

Ze względu na ilustrowanie odpowiedniej metody wywołania JQ, załóżmy, że strumień podmiotów JSON pochodzi z curl COMMAND i że chcemy drugiego przedmiotu (to znaczy, z indeksem 1).

Wezwanie

curl COMMAND | jq --argjson i 1 -n -f program.jq

(Uwaga opcja wiersza polecenia -n!)

Program.jq

def get($i):
  label $done
  | foreach inputs as $input (-1; .+1;
      if $i == . then $input, break $done else empty end);

get($i)
0
peak 2 czerwiec 2018, 17:12