0

On Windows, I am trying to do an in-place edit of simple JSON files that are malformed. My files look like this, with first object duplicated.

{
  "hello":"there"
}
{
  "hello":"there"
}

My goal is to have only one object, and discard the second one. I should note that the files have linefeeds, as shown here. End file should look like

{
  "hello":"there"
}

I can match the first group using a regexp like ^({.*?}).*. This is fairly simple.

Seems like a perfect job for sed in-place editing. But apparently no matter what combination of escaping I do in sed, I can't match the brackets. I am using (GNU sed) 4.9 patch by Michael M. Builov.

Some results I get:

# as per original regexp
sed.exe -E "s,^({.*?}).*,d,g" double.json
     ->  -e expression #1, char 16: Invalid preceding regular expression

# trying to escape paranthesis
sed.exe -E "s,^\({.*?}\).*,d,g" double.json
     ->  -e expression #1, char 18: Invalid content of \{\}

# escaping curly brackets
sed.exe -E "s,^\(\{.*?\}\).*,d,g" double.json
     -> Works, but original file is returned (no match)

Is it possible at all on Windows ? According to this and this comment it seems that Windows for some reason does not like curly brackets with sed.

Note: tested in WSL/Ubuntu, and got same result.

MyICQ
  • 987
  • 1
  • 9
  • 25

2 Answers2

0

You can try this GNU sed

$ sed -Ez 's/((\{[^}]*}).*)\2/\1/' input_file
{
  "hello":"there"
}
HatLess
  • 10,622
  • 5
  • 14
  • 32
  • this worked with `(GNU sed) 4.5` for Windows, but not the patched version. And it worked *only* if the last object ended with a linefeed. Unfortunately I can't guarantee it will. So not fully there yet. I also need to analyze the expression further - sed is a bit new to me. – MyICQ Dec 09 '22 at 08:26
  • Sorry @MyICQ I have not been able to test it just yet but have made a slight change. – HatLess Dec 09 '22 at 09:26
0

jq command line tool is handy to use for JSON values, even on Windows. You can download by this link as an example.

Then save the command

inputs

into a file called double.jq, and then call from command line by

[Windows key]+ cmd

cd to_the_path_where_the_files_reside    
jq -f double.jq <double.json

if there are more than two independent objects within the file double.json such as

{
  "hello":"there"
}
{
  "hello":"there"
}
{
  "hello":"there"
}
{
  "hello":"there"
}

and want to pick the first one only, then convert code of the double.jq to

[inputs] | unique | .[]
Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55