0

I need to replace some text in a file and add couple of lines before the end of file.

I have this:

{
  "something": "option1",
  "other": [
    "value",
  ]
}

and I need this:

{
  "something": "option2",
  "other": [
    "value",
  ],
  "more": {
    "stuff": "yey!"
  }
}

I tried this scipt:

stuff=$1

value=",
  \"more\": {
    \"stuff\": \"$stuff\"
  }"

sed -e "s/option1/option2" -e '$ \i$value' \
  file1.json > file2.json

but I get:

{
  "something": "option2",
  "other": [
    "value",
  ]
$value
}

How do I do this properly?

6
  • single quotes are literal strings that don't expand variables Commented Oct 24, 2017 at 21:51
  • @Austin_Anderson I know that's why I'm getting this result, but don't know how to expand variable in this case... I tried different things, but this is the only one that doesn't throw error (; Commented Oct 24, 2017 at 21:52
  • also regex can't parse json, so if you need anything more than a one off, you need to use some json library, like in a perl or python script Commented Oct 24, 2017 at 21:56
  • what is the context? do you have like 50+ tiny json files that all look like your first box? is this part of a large json file? I'm assuming it's not just what you've posted or else you would have just typed it in manually Commented Oct 24, 2017 at 22:00
  • I want to modify configuration file like this, so I can run some more commands with modified version... It's a larger file, but it could be a simple text file. Question is how to insert text from variable one line before file end... Commented Oct 24, 2017 at 22:06

2 Answers 2

1

The only right way to manipulate json data is using JSON parsers/processors. Period!

Use jq processor, it'll make your "relationship" with JSON easy and comfortable:

Valid JSON file1.json:

{
  "something": "option1",
  "other": [
    "value"
  ]
}

stuff="jq got you"
jq --arg stuff "$stuff" '.more = {stuff: $stuff}' file1.json

The output:

{
  "something": "option1",
  "other": [
    "value"
  ],
  "more": {
    "stuff": "jq got you"
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

It's not the better way, but if you want with sed, you can try

With gnu sed

echo "$value" | sed ':A;/\n.*}/!{N;bA};h;s/.*//;N;$!{s/.*\n//;:B;N;$!{H;s/option1/option2/;s/\n.*//p;g;s/\(.*\)\(\n.*\n[^\n]*\)/\1/;x;s/\(.*\n\)\([^\n]*\)/\2/;bB}};H;g;s/\(.*\n\)\([^\n]*\)\(\n[^\n]*\)/\2/;G;s/\(.*\n\)\([^\n]*\n\)\([^\n]*\)/\1\3/;s/\([^\n]\)\(\n\)\(.*\)/\1\3/' /dev/stdin infile

Or with OpenBSD sed

cat scriptsed
sed ':A;/\n.*}/!{N;bA
}
h;s/.*//;N;$!{s/.*\n//;:B;N;$!{H;s/option1/option2/;s/\n.*//p;g;s/\(.*\)\(\n.*\n[^\n]*\)/\1/;x;s/\(.*\n\)\([^\n]*\)/\2/;bB
}
}
H;g;s/\(.*\n\)\([^\n]*\)\(\n[^\n]*\)/\2/;G;s/\(.*\n\)\([^\n]*\n\)\([^\n]*\)/\1\3/;s/\([^\n]\)\(\n\)\(.*\)/\1\3/'

And call it like that

(echo "$value";cat infile) | ./scriptsed

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.