1

I want with sed to replace what is in [….] with target key=new_string

more /tmp/file
my.uri=http://[linux123]:8080

we try this

key=new_string

sed s"/[*]/$key/g" /tmp/file

but file not changed

more file
my.uri=http://[linux123]:8080

what is wrong with my sed?

Expected results should be ( without Square brackets )

more file
my.uri=http://new_string:8080
  • 1
    This post: https://unix.stackexchange.com/questions/95884/how-can-i-get-my-sed-command-to-make-permanent-changes-to-a-file describes how to do the change in-place, but also your sed command needs to be fixed. You have to match an opening bracket, any character not being a closing bracket, and to a closing bracket. And the replacement part should include the brackets too. – thanasisp Nov 01 '20 at 20:15
  • see my update , its should be without [ ] –  Nov 01 '20 at 20:21
  • 2
    Then the replacement pattern is good, just the variable, the matching pattern needs to be \[[^]]*\]. This is a regular expression, to be used in sed. If you had a star alone instead of [^]]* it would be a shell glob expression (matching anything). – thanasisp Nov 01 '20 at 20:25

2 Answers2

1

First of all, you have to ensure that your key variable does not contain any characters with special meaning for your sed command, like for example / which is the default separating character for the sed substitution. In such a case you could use a different character, for example like this "s@pattern@replacement@g" file.

Then you need to match from an opening until the corresponding closing bracket. That would be \[.*\] but sed is greedy: In case your line contains [text1] text2 [text3], sed will match all of this. So you need to define, instead of .*, any character which is not a closing bracket, zero or more times: [^]]*.

Note that in the above, we don't need to escape (\]) the bracket in the middle, because sed awaits for at least one character to exclude after the caret (^), so it will not misread this as the closing bracket of the list of the excluded characters, but as a literal bracket.

Now if you want to make the change in-place, you can use -i like described in this post. But first test without -i, check a part of the output to see if it looks good.

So this sed is expected to work for your case:

sed -i "s/\[[^]]*\]/$key/g" file
thanasisp
  • 8,122
1

Your regexp is missing a '.' before '*'. If you are sure, that there is only one opening, and one closing bracket, then this should work:

sed "s/\[.*\]/$key/g" /tmp/file

This prints to the stdout, if you want to edit in-place, use sed -i.