1

I have a config file that looks like this:

...
[env.staging]
name = "something"
...
[env.production]
name = "something"
...

I'm trying to replace the value of name on a specific environment using regex in the sed command in bash, but when I try to find the line by its section followed by a New Line, it doesn't work:

sed -i -e '/\[env\.production\]\nname =/s/=.*/= \"something_else\"/' config.toml

But the following command works fine, and of course, changes the name variable of both environments which is not desired.

sed -i -e '/name =/s/=.*/= \"something_else\"/' config.toml

Any ideas on how to achieve the correct result? (All my files are using LF line endings)

1
  • consider updating the question with more sample data that's indicative of your environment; eg, does the name = "..." entry always come immediately after the stanza/header? will you only be changing the name = "..." entry or could you need the ability to change other variables, too? Commented Sep 8, 2021 at 14:09

2 Answers 2

3

sed works line by line by default. You cannot match across multiple lines unless you use features to bring in multiple lines to the pattern space.

$ sed '/\[env\.production]/ {n; s/=.*/= "something_else"/}' config.toml
...
[env.staging]
name = "something"
...
[env.production]
name = "something_else"
...

n command will replace the pattern space with the next line. Use N when you need to process both lines together.

{} is used to group commands.


I would also suggest to use a toml tool like dasel instead of sed for such cases.

Sign up to request clarification or add additional context in comments.

3 Comments

and one more thing, how can I make sure it's the "name" variable I'm changing and nothing else. just in case...
you could use name.*=.* in the search term and use name in the replacement as well..
May you please give me an example? Besides, is this gonna work if the name variable is not on the first line after the header?
1

I've created some additional sample data for demonstration purposes:

$ cat config.toml
...
[env.staging]
id = 1
name = "something"
name2 = "something"
date = 2021/08/03
...
[env.production]
id = 2
name = "something"
name2 = "something"
date = 2022/01/23
...
[env.test]
id = 3
name = "something"
name2 = "something"
date = 2021/11/15
...

One sed idea using a range to find the desired section and then apply the change to said section:

$ sed '/\[env.production\]/,/^name = ".*$/ s/^name = ".*$/name = "something_else"/' config.toml
...
[env.staging]
id = 1
name = "something"
name2 = "something"
date = 2021/08/03
...
[env.production]
id = 2
name = "something_else"
name2 = "something"
date = 2022/01/23
...
[env.test]
id = 3
name = "something"
name2 = "something"
date = 2021/11/15
...

NOTES:

  • we don't know what the rest of the config sections look like so I went a bit overboard by specifying the entire line (^name = ".*$)
  • once OP is satisfied with the answer the -i option can be added to perform the 'in place' update of config.toml

7 Comments

Thank you as well ;) but I liked the other solution which has a shorter syntax.
it may have a shorter syntax but it does not answer your question of how to ensure only the name = "..." entry is modified; in fact, if name = "..." does not follow immediately after the stanza/header then you'll modify the wrong row, eg, run the other answer against my sample data; on the other hand, if you know you'll always be modifying the one row that immediately follows the stanza/header ... then the other answer is sufficient
So, your solution works regardless of where the variable is under that header? That's for sure more accurate then.
I just ran some tests and your solution is better in that regard, so I'll use yours instead. Thanks again.
My config file exactly looks like the sample, actually, it's a wrangler.toml from CloudFlare Workers. Your command works flawlessly as far as I tested. But of course, I can consider using other tools later, as for now, I don't want to make it too complex because I'm running this script on my GitLab Runner and prefer not to install extra tools on the server.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.