0

I have a test property file with this in it:

-config.test=false
config.test=false

I'm trying to, using sed, update the values of these properties whether they have the - in front of them or not. Originally I was using this, which worked:

sed -i -e "s/#*\(config.test\)\s*=\s*\(.*\)/\1=$(echo "true" | sed -e 's/[\/&]/\\&/g')/" $FILE_NAME

However, since I was basically ignoring all characters before the match, I found that when I had properties with keys that ended in the same value, it'd give me problems. Such as:

# The regex matches both of these

config.test=true
not.config.test=true

Is there a way to either ignore the first character for a match or ignore the initial - specifically?

EDIT:

Adding a little clarification in terms of what I'd want the regex to match:

config.test=false      # Should match
-config.test=false     # Should match
not.config.test=false  # Should NOT match
ev0lution37
  • 1,013
  • 2
  • 10
  • 25

2 Answers2

1
sed -E 's/^(-?config\.test=).*/\1true/' file

? means zero or 1 repetitions of so it means the - can be present or not when matching the regexp.

Ed Morton
  • 157,421
  • 15
  • 62
  • 152
0

I found some solution for a regex of a specific length instead of ignoring the first character with sed and awk. Sometimes the opposite does the same by an easier way.

If you only have the alternative to use sed I have two workaround depending on your file.

If your file looks like this

$ cat file
config.test=false
-config.test=false
not.config.test=false

you can use this one-liner

sed 's/^\(.\{11,12\}=\)\(.*$\)/\1true/' file

sed is looking at the beginning ^ of each line and is grouping \( ... \) for later back referencing every character . that occurs 11 or 12 times \{11,12\} followed by a =.

This first group will be replaced with the back reference \1.

The second group that match every character after the = to the end of line \(.*$\) will be dropped. Instead of the second group sed replaces with your desired string true.

This also means, that every character after the new string true will be chopped.

If you want to avoid this and your file looks like

$ cat file
config.test=true      # Should match
-config.test=true     # Should match
not.config.test=false  # Should NOT match

you can use this one-liner

sed 's/^\(.\{11,12\}=\)\(false\)\(.*$\)/\1true\3/' file

This is like the example before but works with three groups for back referencing.

The content of the former group 2 is now in group 3. So no content after a change from false to true will be chopped.

The new second group \(false\) will be dropped and replaced by the string true.

If your file looks like in the example before and you are allowed to use awk, you can try this

awk -F'=' 'length($1)<=12 {sub(/false/,"true")};{print}'

For me this looks much more self-explanatory, but is up to your decision.

In both sed examples you invoke only one time the sed command which is always good.

The first sed command needs 39 and the second 50 character to type. The awk command needs 52 character to type.

Please tell me if this works for you or if you need another solution.

John Goofy
  • 980
  • 1
  • 6
  • 19