0

I'm a bit lost with this jq command. I have a json file like that:

...

{
    "class": "classOne",
    "title": "title1",
    "text": "text1"
},
{
    "class": "classTwo",
    "title": "title2",
    "text": "text2"
},

...

What I'm trying to do is replace values of texts with another value, depending on the value of title.

How can I do, and how in general can I replace one value depending on another from the same 'group'? Plus, can I specify 'only first' or 'general' following the way sed works with '.../g'?


Edit

I want to be able to work with any depth of my json, that's why my included code isn't very big. Basically I want to modify a value depending on the value of another key always in the same object.


Tyvm.

Arainty
  • 91
  • 9
  • Please follow the [mcve] guidelines. It will avoid a lot of confusion and wasted time. – peak Oct 18 '20 at 16:38

1 Answers1

0

Assuming the new value of .text depends on .title in the same JSON object, one model you could follow would be:

map(if .title | test("REGEX") then .text = ... else ... end)

jq has both sub (like sed's 's' but by default without "g") and gsub (like sed's 's' but with "g"), as per the jq manual at https://stedolan.github.io/jq/manual/#RegularexpressionsPCRE

Using walk/1

If you want to make a change in all objects with both .title and .text, you could use walk/1 along the following lines:

walk(if type == "object" and has("title") and has("text")
     then if .title | test("REGEX") then .text = ... else ... end
     else . end)

Edit by @Arainty: using test is just for illustration; use == to match the exact value. (.title=="STRING")

peak
  • 105,803
  • 17
  • 152
  • 177
  • Thank you! However I've got the error `Cannot index string with string "title"` with this command (`jq 'map(if .title | test("testValue") then .text = "newvalue" else "" end)' myfile.json`, also I want to do in-place replacement, and I assume it works like that) – Arainty Oct 18 '20 at 16:14
  • (a) You most likely want `else . end`. (b) Without seeing your input, it's hard to know what the source of the problem you encountered is. (c) If by "in-place replacement" you mean overwriting the input file, see https://stackoverflow.com/questions/36565295/jq-to-replace-text-directly-on-file-like-sed-i but BE CAREFUL! – peak Oct 18 '20 at 16:37
  • (a) thanks! same problem obviously (b) I could provide you a link, but I want it to work in any case, no matter the 'depth' of the object and what's around it. Also I have a lot of these replacing commands to do, and always in an object scope (changing one value depending on another of the same object) (c) I'm working in a test file so I don't care now, and I will probably use `sponge` – Arainty Oct 18 '20 at 16:56
  • a. If you run into a specific problem and want help, it should be possible to provide a simple specific example as per mcve. b. If you want the operation to be performed at any depth, then that could be stated in the requirements; it sounds like you might want to use `walk` – peak Oct 18 '20 at 18:49
  • sorry for the lack of information, I edited the main post to clarify things. could you provide me an example with `walk` please? – Arainty Oct 18 '20 at 19:25
  • Please see update. For future reference, though, it's a good idea to follow mcve, even if it's just to avoid downvotes. – peak Oct 18 '20 at 20:45
  • thank you very much! I added some info to your answer and validated it :) – Arainty Oct 18 '20 at 21:57