Home > front end >  Edit with sed using capturing group of curly braces (windows)
Edit with sed using capturing group of curly braces (windows)

Time:12-09

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.

CodePudding user response:

You can try this GNU sed

$ sed -Ez 's/((\{[^}]*}).*)\2/\1/' input_file
{
  "hello":"there"
}

CodePudding user response:

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 | .[]
  • Related