Search code examples
jsonjqjsonlines

Get all values of a specific key based on another key specific value


I have a jsonlines format file with more than 1 mln lines (let's say BIG.json). I want to filter this file based on some key/value dependencies (explained below).

All lines are, of course, structured in the same way, here are 5 consecutive lines of this file:

{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.4", "txt": "Rzeczpospolita Polska powraca do zasad demokratycznych, a zatem po bez mała 60 latach znów będziemy mieli w naszym kraju samorząd terytorialny. A bez niego wszelkie dysputy o demokracji, o państwie obywatelskim i o suwerenności społeczeństwa pozostałyby pustym gadulstwem."}
{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.5", "txt": "Powiedziałem, że Polska wraca do zasady samorządności gmin po bez mała 60 latach i to jest oczywista prawda, bo przed wybuchem wojny w roku 1939, już od połowy lat trzydziestych, samorząd terytorialny w ówczesnym państwie polskim był znacznie ograniczony i poddawany coraz surowszej kontroli administracji rządowej. Z takim szacunkiem i czcią wspominany dzisiaj przez nas prezydent m. st. Warszawy, człowiek wielkich zasług i wielkiego męstwa, Stefan Starzyński, nie był przecież prezydentem Warszawy z wyboru, był prezydentem komisarycznym, bo po roku 1934 samorząd terytorialny w Warszawie już praktycznie nie funkcjonował w sposób prawdziwie demokratyczny."}
{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.6", "txt": "Stąd właśnie dzisiejsze zetknięcie się z tą problematyką jest niejako pierwszym spotkaniem Polaków z samorządnością. Już niemal nikt nie może pamiętać tych spraw z osobistego doświadczenia. Ostatni żyjący dzisiaj jeszcze radni gmin i miast z tamtej epoki są starcami, a przez wszystkie minione lata uczyniono wielki wysiłek, aby sprawy samorządu terytorialnego z ludzkiej pamięci wymazać, a wyobrażenia o samorządzie gruntownie zafałszować."}
{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.7", "txt": "O cóż idzie w kwestii samorządu terytorialnego i na czym polega cała sprawa z punktu widzenia filozofii demokratycznego państwa? Idzie po prostu o to, aby obywatele tego państwa wzięli w swoje ręce odpowiedzialność za los zbiorowy. Idzie o to, aby gmina, to znaczy określone terytorium, na którym mieszka określona liczba mieszkańców i na którym znajdują się określone urządzenia użyteczności publicznej, sama decydowała o swoim losie, o swoich zamiarach, o planach swego rozwoju, o najwłaściwszym wykorzystaniu duchowych i materialnych sił lokalnej społeczności."}
{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.8", "txt": "Jest to zmiana rewolucyjna, ponieważ wymaga od milionów ludzi zupełnie nowych zachowań i zupełnie nowego stosunku do życia publicznego. Przez. kilka dziesięcioleci obywatel PRL przywykł, że wszechobecne państwo i jego aparat urzędniczy decydowało niemal o wszystkim. Obywatel PRL mieszkał w państwowym mieszkaniu, kupował w państwowym sklepie państwowy chleb i państwowe mleko, pracował na państwowej posadzie, spał na państwowym łóżku i mogło się zdawać, że oddycha państwowym powietrzem. Niemal wszystko pozostawało w gestii państwa, a obywatel nie był podmiotem życia publicznego, ale przedmiotem wszechobecnej manipulacji."}
{"filename": "ppc/1989-1991/senat/posiedzenia/pp/198991-snt-ppxxx-00017-01/text_structure.xml", "period": "1989-1991", "title": "17 posiedzenie Senatu PRL/RP", "date": "1990-01-19", "person": "Senator Andrzej Szczypiorski", "txt_id": "u-59.9", "txt": "Towarzyszyło nam, i to zrozumiałe, poczucie zniewolenia, wyobcowania i kompletnej bezradności, a także jako naturalna reakcja na taki stan rzeczy, obojętność na sprawy publiczne, lekceważenie własności, która była w gruncie rzeczy niczyja, oraz niechętny lub zgoła wrogi i pełen wzgardy stosunek do każdego urzędu. Obywatel, który czuł się nieustannie wyzyskiwany i oszukiwany przez aparat państwa usiłował w swojej bezbronności i bez radności oszukiwać państwo, trwonić wspólny majątek i lekceważyć przepisy prawa."}

This file is the effect of parsing multiple XML files and extracting data out of them.

I would like to filter some lines based on "person" key value and put them to another jsonlines file, preferably named the same as "person" key value. For instance, file named "Senator Andrzej Szczypiorski.json" should contain each line of BIG.json that had exactly "Senator Andrzej Szczypiorski" value under the "person" key.


Solution

  • Assuming your input file is input.txt, try this command:

    jq 'select(.filename=="path_to_file2" and (.date | contains("2016-10-")))' input.txt
    

    Adjust the conditions to match your needs. Use == for exact match and contains(element) to match using a substring.

    In order to get another jsonlines file as output, add the -c (compact output) flag before the JQ script. You should also redirect the output to a new file:

    jq -c 'select(.filename=="path_to_file2" and .date=="2016-10-22")' input.txt > output.txt