LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   sed and regex issues (https://www.linuxquestions.org/questions/linux-general-1/sed-and-regex-issues-4175555789/)

ravedog 10-10-2015 10:40 AM

sed and regex issues
 
Hey guys,

Searched here for this and found lots of answers, but none seems to work :)

The case: I have an ini file that lists a lot of settings like this:

Code:

SettingA=true
SettingB=false
SettingC=
SettingD=Somethingelse
SettingE=

and so on. In a bash script im trying to replace "SettingC=" if it looks exactly like that. So if anyone went and added "SettingC=true" it cant match.

So I have tried with sed and regex word boundaries, but it does not work due to some unknown reason.

This is what i try to run from inside a script:
Code:

sed -i "s/\bSettingC=\b/SettingC=false/g" /path/to/ini_file
However that does not work.

I have also tried with \<\>, which didn’t work either. Anyone that can enlighten me what im doing wrong here? :)

Cheers!

R

rknichols 10-10-2015 11:48 AM

It's simple enough if you don't mind needlessly updating a file with the same setting it already had.
Code:

sed -i "s/SettingC=.*/SettingC=false/" /path/to/ini_file
To avoid that takes a bit more work.
Code:

sed -i "/SettingC=false\$/b;s/SettingC=.*/SettingC=false/"
What that does is first test whether the line is already "SettingC=false" (explicitly anchored to the end of the line so that "false123" will not match) and branch to the end of the script if true, otherwise do the replacement.

[EDIT]And, a bit of testing reveals that sed is not as smart as I thought it was and will replace the file even if no changes were made, so there's no point in adding that test.[/EDIT]

In both cases, the regex ends with ".*" so that anything following the equals sign will be replaced.

There are lots of things that could be done to make this more robust with regard to whitespace, lines like "MySettingC=whatever", etc. While sed certainly could do all that (It is, after all, a Turing-complete language.), eventually you reach a point where it is just not a suitable language for the task at hand.

sycamorex 10-10-2015 12:38 PM

What about the following? It'll only match SettingC= followed by end of line.

Code:

sed 's/SettingC=$/&false/' file

ravedog 10-10-2015 12:44 PM

Thanks for the quick reply rknichols!

With the top example
sed -i "s/SettingC=.*/SettingC=false/" /path/to/ini_file
It replaces even if the string is "SettingC=" or "SettingC=true" and that seems to be ok and working but not what i was after.
The second example you had, did not actually replace at all. Please note that these strings are on single row and they start the row as my example above, so no need to take any of that in to consideration.

What im after is to ensure that the string is exactly "SettingC=" and if it, replace with "SettingC=false". I do fully agree with you on right tool for right job and this to me seemed like work for sed. :)

Thanks!

br,

R

ravedog 10-10-2015 12:49 PM

Quote:

Originally Posted by sycamorex (Post 5432645)
What about the following? It'll only match SettingC= followed by end of line.

Code:

sed 's/SettingC=$/&false/' file

Spot on and did the trick! Thanks for your help guys

rknichols 10-10-2015 01:00 PM

Quote:

Originally Posted by ravedog (Post 5432648)
What im after is to ensure that the string is exactly "SettingC=" and if it, replace with "SettingC=false". I do fully agree with you on right tool for right job and this to me seemed like work for sed.

Sorry, misunderstood what you wanted. This is easier -- just include the end-of-line mark in your regex.
Code:

sed -i "s/SettingC=\$/SettingC=false/" /path/to/ini_file
# or
sed -i 's/SettingC=$/SettingC=false/' /path/to/ini_file

The "g" flag is pointless since there cannot be more than one match in the line. Note the difference in quoting. You need to get the "$" character past the shell. sed needs to see just the "$" and not "\$".

Again, you might want to ignore whitespace, especially at the end of the line:
Code:

sed -i "s/SettingC= *\$/SettingC=false/" /path/to/ini_file

ravedog 10-11-2015 07:09 AM

@rknichols: Thanks for explaining and the additional examples.

Thanks for very informative answers both!

Cheers,

R


All times are GMT -5. The time now is 02:50 PM.