2017-02-15 31 views
12

Mam plik json i chcę do niego dodać nową tablicę obiektów. Próbuję użyć wiersza poleceń jq. Kiedy patrzyłem na Internet, to polecenie to zrobić, nie tylko dla obiektów zapytania w pliku Json. Ale nie mogę dowiedzieć się, jak użyć polecenia ADD na jq. Mój plik JSON jest raport-2017-01-07.json >>Dodaj nowy element do istniejącej tablicy JSON, używając jq

{ 
    "report":"1.0", 
    "data":{ 
     "date":"2010-01-07", 
     "messages":[ 
     { 
      "date":"2010-01-07T19:58:42.949Z", 
      "xml":"xml_samplesheet_2017_01_07_run_09.xml", 
      "status":"OK", 
      "message":"metadata loaded into iRODS successfully" 
     }, 
     { 
      "date":"2010-01-07T20:22:46.949Z", 
      "xml":"xml_samplesheet_2017_01_07_run_09.xml", 
      "status":"NOK", 
      "message":"metadata duplicated into iRODS" 
     }, 
     { 
      "date":"2010-01-07T22:11:55.949Z", 
      "xml":"xml_samplesheet_2017_01_07_run_09.xml", 
      "status":"NOK", 
      "message":"metadata was not validated by XSD schema" 
     } 
     ] 
    } 
} 

używam poniższego polecenia >>

$ cat report-2017-01-07.json | jq -s '.data.messages {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}' 
jq: error: syntax error, unexpected '{', expecting $end (Unix shell quoting issues?) at <top-level>, line 1: 
.data.messages {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}    
jq: 1 compile error 

Próbowałem już innej kombinacji poleceń ale ja zawsze kończąc kompilacja błędów. Jakaś wskazówka na ten temat? Dzięki!

wyjście musi wyglądać >>

{ 
    "report": "1.0", 
    "data": { 
     "date": "2010-01-07", 
     "messages": [{ 
      "date": "2010-01-07T19:58:42.949Z", 
      "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
      "status": "OK", 
      "message": "metadata loaded into iRODS successfully" 
     }, { 
      "date": "2010-01-07T20:22:46.949Z", 
      "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
      "status": "NOK", 
      "message": "metadata duplicated into iRODS" 
     }, { 
      "date": "2010-01-07T22:11:55.949Z", 
      "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
      "status": "NOK", 
      "message": "metadata was not validated by XSD schema" 
     }, { 
      "date": "2010-01-07T19:55:99.999Z", 
      "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
      "status": "OKKKKKKK", 
      "message": "metadata loaded into iRODS successfullyyyyy" 
     }] 
    } 
} 
+0

nie wiem to dobrze, ale nie jest to problem, który .data.messages jest arrray? Więc potrzebujesz czegoś takiego jak .data.messages. [] –

+0

Przepraszam, nie działa –

+0

Ok - przeczytaj dokumenty i zainstaluj jq (na Windowsie) i wypróbuj - otrzymasz ten sam błąd co Ty. Wygląda na to, że powłoka systemu Windows ma problemy ze sposobem przesyłania podwójnego cudzysłowu do strumienia, który wywołuje jq. Nie można uzyskać nic do pracy, więc nie ma odpowiedzi na twoje pytanie, ale możesz chcieć spojrzeć na unikanie podwójnych cudzysłowów w komendzie jq. Tak więc '' date "' stanie się '\" date \ "' itp. –

Odpowiedz

15

|= .+ część filtr dodaje nowy element do istniejącej tablicy. Można użyć jq z filtrem jak

jq '.data.messages[3] |= . + {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}' inputJson 

Aby uniknąć stosując ustalony wartość długości 3 i dynamicznie dodać nowy element, użyj . | length która zwraca długość, która może być użyta jako następnego indeksu tablicy, tj

jq '.data.messages[.data.messages| length] |= . + {"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}' inputJson 

(a), zgodnie z sugestią piku w komentarzach, za pomocą operatora += sam

jq '.data.messages += [{"date": "2010-01-07T19:55:99.999Z", "xml": "xml_samplesheet_2017_01_07_run_09.xml", "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}]' 

, który wytwarza dane wyjściowe zgodnie z potrzebami.

{ 
    "report": "1.0", 
    "data": { 
    "date": "2010-01-07", 
    "messages": [ 
     { 
     "date": "2010-01-07T19:58:42.949Z", 
     "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
     "status": "OK", 
     "message": "metadata loaded into iRODS successfully" 
     }, 
     { 
     "date": "2010-01-07T20:22:46.949Z", 
     "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
     "status": "NOK", 
     "message": "metadata duplicated into iRODS" 
     }, 
     { 
     "date": "2010-01-07T22:11:55.949Z", 
     "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
     "status": "NOK", 
     "message": "metadata was not validated by XSD schema" 
     }, 
     { 
     "date": "2010-01-07T19:55:99.999Z", 
     "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
     "status": "OKKK", 
     "message": "metadata loaded into iRODS successfullyyyyy" 
     } 
    ] 
    } 
} 

Zastosowanie jq-play do wyschnięcia uruchomić jq-filter i optymalizacji jakikolwiek sposób chcesz.

+0

Ponieważ celem jest tylko dodanie elementu, lepiej byłoby użyć + =, ale warto zauważyć, że '.data.messages [3] | =. + X' można tutaj uprościć do '.data.messages [3] = X', ponieważ' .' na RHS jest faktycznie po prostu 'null'. – peak

+0

(tutaj użytkownik Windows JQ): Zastanawiam się, czy możliwe jest zapisanie tych nowych danych do tego samego (wejściowego) pliku, zamiast tworzenia tymczasowego pliku, który musi mieć zmienioną nazwę. –

+0

@ script'n'code - Korzystanie 'gąbka' prawdopodobnie nadal jest najlepszą opcją, jeśli ją masz lub możesz ją zainstalować (jest to część moreutils). – peak

12

Zamiast używać |= tutaj, jest o wiele lepiej jest użyć +=:

.data.messages += [{"date": "2010-01-07T19:55:99.999Z", 
    "xml": "xml_samplesheet_2017_01_07_run_09.xml", 
    "status": "OKKK", "message": "metadata loaded into iRODS successfullyyyyy"}]