Jq sort_by probléma

Jq sort_by probléma
2021-02-25T21:19:28+01:00
2021-02-26T10:39:23+01:00
2022-08-12T01:05:31+02:00
mabet
Van egy json állomány:
{ "a":1, "b":2 } { "a":9, "b":3 }{ "a":4, "b":99 }

Szeretném a jq program segítségével, az "a" mezőre rendezve megkapni az adatokat.

Ha ebben a formában adom meg: [{ "a":1, "b":2 }, { "a":9, "b":3 }, { "a":4, "b":99 }] akkor működik.
Viszont nekem az első formában áll rendelkezésemre az összes adat.
Ezekből hogy lehetne tömböt készíteni?
Vagy hogyan lehetne tömb nélkül az egymást követő... nem is tudom, minek nevezhetném ezeket az adatdarabokat... megvan: objektumok listája. Naszóval: hogy lehetne őket rendezni, ha csak úgy magukban vannak, nincsenek tömbbe pakolva/hogyan lehetne ebből a listából tömböt gyártani?


ui: "A téma címét nagybetűvel kezdjük és az ékezeteket is kirakjuk!" - ez a kioktató stílus már a stackexchenge-en is kiverte a biztosítékot...
Mutasd a teljes hozzászólást!
Most már én is felraktam egy jq-t. Valóban kell a -s, meg még kis trükközés a tömbök kibontásával és visszacsomagolásával:

csaboka@DESKTOP-NKH2ODI:~$ cat > a.json { "f1": {}, "f2": 0, "f3": [ {"a":1, "b":2 }, { "a":9, "b":3 }, { "a":4, "b":99 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat > b.json { "f1": {}, "f2": 0, "f3": [ {"a":42, "b":13 }, { "a":-5, "b":3 }, { "a":123, "b":999 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat > c.json { "f1": {}, "f2": 0, "f3": [ {"a":52, "b":13 }, { "a":-15, "b":33 }, { "a":321, "b":-999 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat *.json | jq -s '[.[].f3[]] | sort_by(.a)'
Ez nekem szépen visszaadja az összes f3-akon belüli tömbelemet, a szerint rendezve.
Mutasd a teljes hozzászólást!

  • Honnan van ez a "json állomány"?
    Csak mert ha tényleg ez van benne (így, ahogy leírtad), akkor az igazából nem json, csak hasonlít rá.
    Mutasd a teljes hozzászólást!
  • Gondoltam, egyértelmű, hogy tesztadat. :)
    Ez már jq-n belül egy filter kimenete egyébként.
    De eredetileg is ilyesmi minden fájl:
    {
      f1: { ... }
      f2: 0
      f3: [ { ... itt vannak a fent kiemelt adatok, mint tömbelemek ... } ]
    }


    Erre jön a jq:

    cat *.json | jq '.f3[] | select(...) | { a:.f1a, b:.f1.b }'

    És ezt szeretném én "a"-ra rendezni. De a sort_by tömböt követel, de olyat hogy tudnék csinálni ezekből?
    Mutasd a teljes hozzászólást!
  • De a sort_by tömböt követel, de olyat hogy tudnék csinálni ezekből?

    A doksi szerint úgy, hogy szögletes zárójelbe rakod a pipeline-t, aminek a kimenetéből tömböt szeretnél. Nem tudom kipróbálni, de ha jól értelmezem a doksit, akkor:

    cat *.json | jq '[.f3[] | select(...) | { a:.f1.a, b:.f1.b }] | sort_by(.a)'
    Mutasd a teljes hozzászólást!
  • Úgy sem jó. Miután több fájlból jön össze (bár a jq szempontjából elvileg egy), valahogy fájlonként külön tömböt gyárt.
    Egyszerűen képtelen vagyok rávenni, hogy a sok objektumot egyetlen tömbként kezelje.
    Mutasd a teljes hozzászólást!
  • A --slurp kapcsoló esetleg?


    • --slurp/-s:

    Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.
    Mutasd a teljes hozzászólást!
  • Nem, az ilyen triviális dolgokon már végigmentem.
    Hacsak nem néztem el valamit, akkor ezek nem működnek jelen esetben.
    A google összes, legalább látszólag releváns találatát megnéztem, úgy tűnik, az, hogy sok fájlból származnak az adatok, megfekszi a jq gyomrát.
    Mutasd a teljes hozzászólást!
  • Márpedig a --slurp lesz a megoldás. Csak éppen a 'cat' helyett.

    cat *.json | jq <...>
    helyett

    jq -s <...> *.json
    Nálam:

    $ jq -s . f*.json [ { "a": 1 }, { "a": 2 } ]
    Mutasd a teljes hozzászólást!
  • Most már én is felraktam egy jq-t. Valóban kell a -s, meg még kis trükközés a tömbök kibontásával és visszacsomagolásával:

    csaboka@DESKTOP-NKH2ODI:~$ cat > a.json { "f1": {}, "f2": 0, "f3": [ {"a":1, "b":2 }, { "a":9, "b":3 }, { "a":4, "b":99 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat > b.json { "f1": {}, "f2": 0, "f3": [ {"a":42, "b":13 }, { "a":-5, "b":3 }, { "a":123, "b":999 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat > c.json { "f1": {}, "f2": 0, "f3": [ {"a":52, "b":13 }, { "a":-15, "b":33 }, { "a":321, "b":-999 } ] } csaboka@DESKTOP-NKH2ODI:~$ cat *.json | jq -s '[.[].f3[]] | sort_by(.a)'
    Ez nekem szépen visszaadja az összes f3-akon belüli tömbelemet, a szerint rendezve.
    Mutasd a teljes hozzászólást!
  • Próbálnék éles adatoktól mentes tesztet kreálni és feltölteni valahova, hogy érthetőbb legyen, de a kib...ttt M$ által megszállt github, ki tudja, miért, a regisztrációnál azt írja, hogy "your account is flagged" és publikusan nem látszik.
    Úgyhogy bocs, de itt most szünet.
    Nem jók az adatok, amikből kiindultok, a sajátjaim nélkül meg nem tudom megmutatni...
    Mutasd a teljes hozzászólást!
  • Úgy tényleg nincs sok értelme, ha nem azt a struktúrát mutatod nekünk, amivel tényleg dolgozol.

    Pastebin esetleg? Nem feltétlen kell git repó ahhoz, hogy megossz egy hosszabb JSON-t.
    Mutasd a teljes hozzászólást!
  • Azt mutattam, de bocs, itt kiszálltam erről a szemédombról!
    (nem veletek van bajom, hanem az oldal üzemeltetőivel/fejlesztőivel)

    Ez a lekezelő stílus, ahogy visszaugat a szoftverük, nálam kiveri a biztosítékot.

    Kedves házigazdák
    Eredetileg a github szemetéről szóló értekezést próbáltam leírni, de a f a sz sz o p ó szoftverük/fejlesztő mindenbe belekötött. Nekem meg nincs arra időm, hogy az ilyen fehérniggerekkel, mint az ilyen (gyk: PC beszéd nem az én stílusom) küzdjek
    Mutasd a teljes hozzászólást!
  • kurvaanyatok/jqtest
    (github, de ez a félhülye szoftver nem engedi linkelni az URI tartalma miatt :D)
    Ott a generátor, amivel lehet tesztfájlt gyártani, mellette három darab fájl, amiből dolgoznom kéne.
    A "body" alatti tömböket kell kiszedni úgy, hogy egyetlen lista legyen belőlük és ezt a listát tetszőleges mezőre (id, message, reference) rendezni, de úgy, hogy megmaradjanak objektum listának.
    Mutasd a teljes hozzászólást!
  • jq -s '[.[].body[]] | sort_by(.id)' {a,b,c}.json [ { "id": 1006, "message": "random text, de lusta vagyok", "reference": 551783057513 }, { "id": 1766, "message": "random text, de lusta vagyok", "reference": 254465142126 }, ..... { "id": 9653, "message": "random text, de lusta vagyok", "reference": 1030030673570 } ]
    Mutasd a teljes hozzászólást!
  • Ez full ugyanaz, mint amit én javasoltam (persze más mezőnevekkel, mert akkor még nem tudtuk az igaziakat), és amire az volt a válasz, hogy "Nem jók az adatok, amikből kiindultok". Úgyhogy már előre várom, hogy ez miért nem lesz jó
    Mutasd a teljes hozzászólást!
  • Valóban :)
    Mutasd a teljes hozzászólást!
  • No ezt kipróbálom (githubos repo név nem ez lett volna, ha nem szaraxik az első regisztrációmmal :D), hasonlóval annyit tudtam tegnap elérni, hogy fájlonként kaptam tömböket a body adataiból.
    Mutasd a teljes hozzászólást!
  • Úgy próbáld, hogy az input 'cat *.json'!

    A [.[].body[]] eredménye: "Cannot iterate over null", a [.body[]] meg látszólag jó, gyakorlatilag fájlonként készít tömböt az objektumokból, ahelyett, hogy egy tömbként kezelné mindet.

    ui: a fő gondnak az tűnik, hogy sok fájlból kell kiszedni egy struktúra mélyéről a tömböt és azt nem tudom egyetlen tömbbé összehozni. (mongodb-ben már sikerült :) )
    Mutasd a teljes hozzászólást!
  • Hát ez ocsmány, de működni látszik:

    cat *.json | jq ".body[]" | jq ". | sort_by(.id)"

    :)

    Ez megoldható egyetlen jq-val?
    Mutasd a teljes hozzászólást!
  • Amit én írtam legutóbb:

    cat *.json | jq -s '[.[].f3[]] | sort_by(.a)'
    átírva az új mezőnevekre:

    cat *.json | jq -s '[.[].body[]] | sort_by(.id)'

    Ennek cat *.json az eleje és azt adja amit szeretnél. Pontosan mi vele a problémád?
    Mutasd a teljes hozzászólást!
  • Nekem cat-tal is működik, tehát Csaboka2 megoldása már tegnap jó volt.

     Cannot iterate over null (null): az egyik JSON-ben a "body" értéke null. Vagy legyen legalább üres tömb, vagy szűrd ki az ilyen tartalmat.

    A -s pedig kell, nem látom a parancssorodban.
    Mutasd a teljes hozzászólást!
  • Jogos, a kapkodásban a -s kimaradt.
    Fura, most újra lefuttatva már valóban megy. Elsőre nem tudom, mit szúrtam el amikor próbáltam.

    Hozzátartozik, hogy a mezőnevek itt sem az élesből vannak, ez is tesztadat, csak kicsivel közelebb áll a tényleges forráshoz, lehet, hogy az átírásnál sikerült bugot csempésznem bele.
    (a saját, korábban működő, history-ból előhívott parancsokkal is sikerült ilyet előadnom az előbb :D)

    Köszi mindkettőtöknek!

    Érteni nem teljesen értem, de az már az én bajom.
    (a szintaxist nem értem, valahogy nem ehhez vagyok szokva :) )


    ui: megtaláltam. Persze, hogy kimaradt a -s ott is, amikor éles adatokon próbálkoztam vele :(
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd