[KERES] jq okosabban

Fórumok

olyasmit keresek, mint a jq, de tudja modositani is a JSON-t. konkretan pl. van 1 cloudformation param.json-om, ebben az 1ik ParameterKey-hez tartozo ParameterValue-t kene updatelni CLI-bol. Persze python-ban osszerakni par perc, de hatha van vmi kesz tool, amit csak en nem ismerek.

Pl.: a LambdaFunctionName-hez tartozo ParameterValue legyen "hello-897" 

 

[
        {
            "ParameterKey": "LambdaFunctionName",
            "ParameterValue": "hello-world"
        },
        {
            "ParameterKey": "LambdaHandler",
            "ParameterValue": "index.handler"
        },

]

Van ilyen/ilyesmi?

Hozzászólások

jq-ból tudod az outputot módosítani, azt meg tedd bele egy tempfile-ba.

aztán a tempfile-t tedd rá az eredetire

zászló, zászló, szív

A jsonpath emlekeim szerint nem annyira tud transzformalni.  Jq helyenként kevésbé nehezen olvasható (írható) mint a jamespath, meg eleg sok helyen tolják, de összességében az előbbi elég tákolmány, az utóbbinak van rendes specje (meg rendes doksija) , tisztább érzés imho. 

A jq legutobbi versioja 2018-as (1.6.4) es egy csomo vuln. scanner talal benne CRITICAL CVE-t... Pl AWS ECR scanner, snyk, artifactory XRAY, egy rakat auditor es pen-tester kiszurja es pruszkol tole... 
En is eppen azon vagyok hogy lecsereljem valamire ami beszel json-ul a docker image-inkbol...

Nem egészen értem, a JSON elvileg plain text formátum (mint a YAML, INI, XML, RTF, stb.), bármelyik plain text editor módosítja neked. A jq inkább megjelenítésre való, hogy emberi szemmel is olvashatóbb legyen.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Azért gondoltam rá, hogy valaki elmagyarázza. Mert jön valahonnan a JSON kimenet, el nem tudom képzelni, hogy mi gátolja meg, hogy átpipe-olva egy text editorba szerkeszteni lehessen, vagy akár csak sed-del módosítsa az ember. Mert az egész JSON-nak meg hasonló formátumoknak az a lényege, hogy bár gépi feldolgozásra van, de emberi szemmel is olvasható, és könnyen szerkeszthető. Gondolom a kolléga valami kényelmesebb megoldást keres, ami a mezőket ilyen táblázatszerűen módosítja majd neki, de én nem látom értelmét, főleg, hogy csak egyetlen értékpárt kell neki módosítani, ahhoz valahogy pláne felesleges újra feltalálni a kereket, meg mindenféle szutyok extra programot felpakolni érte.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

A json struktúrált dokumentum, lehet hogy a fa minden második szintjén levő a-t kéne lecserélni b-re.

Ezt elég kemény sed-ben megcsinálni, jq-val triviális.

Valamint a jq hajnali 4:30-kor is megcsinálja ezt helyetted, nem kell felkelni és szövegszerkesztővel buzizni.

zászló, zászló, szív

A sor szerkesztők addig működnek ebben az esetben, amíg az input fájl szemre sem változik. Json esetén a sorrend és az egy sorban írom kérdésének változása ugyanazt a json-t eredményezi, mégis másképp kell feldolgozni. Ugyanez a helyzet akkor, ha bekerül egy blokk, ami ugyanolyan nevű mezőt tartalmaz, lásd json-bw ágyazott json. Ezért fontos a struktúra értés a feldolgozó részéről, ami pl egy sed esetén nincs meg

ah, tudtam hogyha ennyire leegyszerusitem akkor valaki erre az edgecase-re talal megoldast. pl ha az "ize" megjelenik a valueban is, akkor maris nemjo a sed... esetleg az ize field megjelenik az elso objecten belul es nested objectben.

A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

Persze, de mondtam, hogy nincs vita és tudom, hogy erre nem igazán alkalmas a sed, csak a konkrét kiragadott példád volt egy magas labda, amit szerintem érzékelhetően poénra vettem és annak megfelelően válaszoltam.

a foo masodik object ize-jet kell atirnii batkamano-ra. probald meg sed-del...

Hint: a felvetésedre (edge case, vagy sem) egyébként pontos megoldást adott a fenti sed. Nyilván ennél bonyolultabbra nem igazán alkalmas ilyen környezetben, de a kérésed teljes mértékben teljesült, megpróbáltam, sikerült. :)

Azt is lehet sed-del, ha az ize a value-ban jelenik meg, csak akkor úgy idézőjelezed, meg stb., hogy ott ne találja meg. Ilyen egyszerű dolognál elég, annak ellenére, hogy a sed, Perl/regexp, awk, stb. nem XML, HTML, JSON, stb. parse-olására való, erre fel is szokták hívni a figyelmet. De már kezdem érteni, hogy neked valami nem interaktív, de magas szintű json editor kell, és ezt a value módosítását csak példának hoztad.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

OFF

A sed-nek ez a -z opciója számomra új, elrakom a szokásos fiókba a többi linuxizm (tudom, GNUizm) közé. Persze hogy a mindig mindent továbbfejlesztő GNU-fejlesztónek mondjuk miért nem volt jó a máshol használt -0 (vagy akár a --null) opció, azt persze nem tudom, de nyilván nem is érdekes; csak én őrülök meg, hogy az amúgy is szétforgácsolódó *X világban miért kell tovább erőltetni a "csakazértis másként csinálom, mint ahogy eddig máshol volt"-ot.

/OFF

Leginkább fordítva zavaró, hogy aki Linux után ül szigorúbban POSIX kompatiblits, tradicionálisabb rendszer elé, ott nem fognak működni a dolgai, amit megszokott, pl. lsblk, watch, meg BSD-ken pl. más a tar formátuma is. Ennek ellenére szerintem vannak a GNU toolokban jó kiegészítések, amik hasznosak, pl. Bash-nek a read parancsában az n és t kapcsoló rendkívül hasznos, karakterszámot és timeout-ot állítja be, ezt hagyományos POSIX shellscripttel megcsinálni oltári nagy és csúnya körbegányolással jár (dd, kill, stb.). Abban teljesen igazad van, hogy azonos funkciójú kapcsolókat nem kéne átkölteniük, az tényleg csak keveréssel jár, és funkcionalitásban nem lesz előnye.

A sed egyébként is egy elég félkész tool, pl. nem tud sortöréseket lecserélni, mert soronként értelmez, és a sortörést lehagyja, nem vizsgálja mintaként. Van erre is körbegányolás, hogy az egész inputot előre beolvastatni egy sorként, de rettenet csúnya. Sajnos vannak ilyen visszásságok, nem tökéletesek ezek az eszközök sem, ismerni kell a korlátaikat és elérhetőségüket, eltérő szintaxisukat egyes rendszereken.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Az, hogy melyik irány a zavaró, az kb. az ember életkorán múlik. Öregebbek jellemzően előbb láttak UNIX-ot, fiatalabbak jellemzően fordítva.

Ami pedig a második felét illeti a megjegyzésednek: man 1 sed, és keress rá az N parancsra!. Íme a példa az O'Reilly-féle sed&awk -ból "ferdítve":

 

Feladat: cseréljük ki a "User Guide" szöveget "Felhasználói kézikönyv"-re - még olyan helyen is, ha sor végén két részre van tördelve:

$ cat lo.txt

ez egy User Guide akárhol - ja megint User Guide ide bele
ez pedig egy User
Guide két sorba tördelve de van itt másik User Guide is
még egy User Guide akárhol
ez pedig egy másik User
Guide két sorba tördelve
utolsó User Guide - vége
vége

$ sed -e '/User$/{

N

's/User\nGuide/Felhasználói\

kézikönyv/

}' -e 's/User Guide/Felhasználói kézikönyv/g' lo.txt

ez egy Felhasználói kézikönyv akárhol - ja megint Felhasználói Kézikönyv ide bele
ez pedig egy Felhasználói
kézikönyv két sorba tördelve de van itt másik Felhasználói kézikönyv is
még egy Felhasználói kézikönyv akárhol
ez pedig egy másik Felhasználói
kézikönyv két sorba tördelve
utolsó Felhasználói kézikönyv - vége
vége

 

De azzal egyetértek, hogy nem szép :-)

Egy csomo programnak van JSON formatumu kimenete, amibol pl. jq-val ki tudsz nyerni dolgokat. Ezt bele tudod tenni egy scriptbe, ami automatikusan meg tudja oldani a problemadat. Plain text editorral az automata adatkinyeres egy fokkal bonyolultabb lenne.

Persze ilyen grep, sed es tarsaival is meg lehetne oldani, de az eleg konnyen eltorik ha minimalisan modosul a kimenet, es sokkal bonyolultabb is, mint egy kifejezetten JSON feldolgozasra irt programmal.

A strange game. The only winning move is not to play. How about a nice game of chess?

jq-val pl. így lehet megoldani, nem tudom, hogy fix stringre akarsz cserélni, vagy a string egy részét akarod kicserélni:

[zmezei@jane ~]$ cat input.json
[
        {
            "ParameterKey": "LambdaFunctionName",
            "ParameterValue": "hello-world"
        },
        {
            "ParameterKey": "LambdaHandler",
            "ParameterValue": "index.handler"
        }
]

[zmezei@jane ~]$ cat input.json |jq 'map((select(.ParameterKey=="LambdaFunctionName") | .ParameterValue) |= "hello-897")'
[
  {
    "ParameterKey": "LambdaFunctionName",
    "ParameterValue": "hello-897"
  },
  {
    "ParameterKey": "LambdaHandler",
    "ParameterValue": "index.handler"
  }
]

[zmezei@jane ~]$ cat input.json |jq 'map((select(.ParameterKey=="LambdaFunctionName") | .ParameterValue) |= sub("world";"897"))'
[
  {
    "ParameterKey": "LambdaFunctionName",
    "ParameterValue": "hello-897"
  },
  {
    "ParameterKey": "LambdaHandler",
    "ParameterValue": "index.handler"
  }
]

Lehet hulye otlet, de nekem elegge bevalt a `jq`-val parhuzamosan: PHP + json_decode(). Az csinal egy full letit php objektumot: modositod ahogy szeretned, majd json_encode()-val kiexportalod. A PHP objektum-absztrakcioja teljesen illeszkedik a JSON-ehoz. Es `php -r ...` modon siman inline, shell-bol is tudod csinalni, akar pipeline-kent is. 

Leginkabb abban kellene szerintem, amilyen scriptnyelv amugy is fent van a dockereben (es amihez ert a kerdezo, de igazabol ennyit par ora alatt meg lehet tanulni). Python, PHP, JS, nagyjabol mindegy. PHP-ben mondjuk van egy aprosag: az ottani array asszociativ, igy a PHP adatszerkezet->JSON konverzio (ill. a manipulacio) eseten figyelni kell, hogy az eredmenybol most lista vagy dictionary lesz-e. Olyan sokat mondjuk nem zavar. Mindhez van JSON lib, illetve a JS alapbol tudja (bar azzal ovatosan kell banni).

A strange game. The only winning move is not to play. How about a nice game of chess?

Amit a feladat sztem. megkíván az a template-lést jó eséllyel, mert feltételezem nem csak 1-2 paramétert kéne updatelni.

Cloudformation-höz bem tudom milyen templating lehetőség van. A jinja2-vel találkoztam, de biztos van más, akár jobb lehetőség is.

Illetve el lehetne gondolkodni mondjuk egy IaC-ben és Git-ben lehetnének a templatek, ha integrálható cloudformation-nel.(ha még nincs ez megoldva.

Ne használj Perl-t mert elég randa:

cat input.json |  perl -MJSON -lane '$a .= $_ }{ foreach (@{decode_json $a}){if ($_->{"ParameterKey"} eq "LambdaFunctionName"){$_->{"ParameterValue"} = "hello-897"} push @b, $_ } print to_json \@b, {utf8 => 1, pretty => 1}'