0

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.

1 Answers1

1

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
axiac
  • 68,258
  • 9
  • 99
  • 134
  • There must be sth wrong with my jsonlines file structure (or the way I'm understanding it). I think I don't get the object-oriented way of building this structure. In my case, in the above example, every single line is an independent object, right? When I try something like this `jq -c 'select(.person=="Senator Zdzisław Nowicki")' BIG.json`, I get the expected output, almost. Almost, because it's the whole line. When I try this `jq -c 'select(.txt | .person=="Senator Andrzej Nowicki")' BIG.json` I'm getting `Cannot index string with string "person"` error. – Daniel Borysowski Oct 07 '19 at 18:18
  • The `jq` command to extract only the `txt` field (after you have selected only some rows) is `jq -c 'select(.person == "Senator Andrzej Nowicki") | .txt' BIG.json`. Your attempt does not work because the filter inside the `select()` first extracts the `txt` field (which is a string) then passes it to the expression `.person == "..."` that cannot access its `person` field (because it is a string, it does not have fields). – axiac Oct 08 '19 at 06:09
  • 1
    Upvoting for both the answer and for clearing things up to me (on how jq filters work). Thank you! – Daniel Borysowski Oct 08 '19 at 10:21