0

I was running a few tests and thought of one I can see myself using frequently.

So I have a few files around that I would usually source as they are common in a lot of things that I would do. I was trying to template it by removing all things after the '=' in a Name=Value pair. This means that instead of:
Foo=Bar
I would have:
Foo=
after I was done using sed to edit my files.

I've tried creating a RegExp statement to do this only remove the Values after the = but I can't seem to create one that will match to a single = and not multiple (e.g. match = but don't match =====)

This is the furthest I got before I decided to post: s/={1}.*/=/g

Could anyone shed some insight? I do not want it removing multiple = as this is the commonly used formatting for comments within my team, they use them to split up data entry sections for easier reading.

Some test values:--

NameOfServer=Foo   
`#`==========  
`#` UserData   
`#`==========

Ideally I would like it to match the '=Foo' in the first line, but not remove the multiple '=' of the commented lines.

Note: I would be using Sed (v4.2) (also Sed within Vim for 'pattern find and replace' if that is any relevance).

  • Why do you need it to not much multiple ==? Do you have sample data we can test our solutions against? – choroba May 24 '18 at 13:23
  • If we were to describe your change it words, would it be: "in lines that have something that is not an equals sign, followed by an equals sign, remove everything after the equals sign"? – Jeff Schaller May 24 '18 at 13:24
  • (I have to note that bash isn't a text editor) – Jeff Schaller May 24 '18 at 13:25
  • Please note that Vim regular expressions and sed regular expressions are very different. (Vim's are much more powerful.) And please explain why s/=.*/=/ does not do what you want. – AlexP May 24 '18 at 13:46
  • Sorry all - I have now added a better explanation and two examples that directly affect what I'm trying to do. – 64Hz May 24 '18 at 14:23
1

A variable is a string that consists of a [a-zA-Z_] character followed by zero or several [a-zA-Z_0-9] characters (in the POSIX/C locale).

We can match these strings that are directly followed by a =, and delete the rest of the line:

sed 's/\([a-zA-Z_][a-zA-Z_0-9]*=\).*/\1/' file

On your example file, this will produce

NameOfServer=
`#`==========
`#` UserData
`#`==========
1

={1}.* is the same as =.*, and will match an equal sign, followed by any amount of any characters. Regexes are usually "greedy", so they try to find the longest match. Using that pattern against a string of equal signs will match the whole string, since there's no way for the regex engine to know you meant characters other than equal signs.

Use =[^=]* to match an equal sign followed by any amount of characters other than equal signs. Or =[^=].* to match an equal sign, followed by any other character, followed by anything.

Or, to match lines with variable assignments more closely, something like

sed -Ee 's/^([a-zA-Z0-9_]+=).*/\1/'

would check that the line looks like a variable assignment, and then remove anything after the =. That assumes the variable names can only contain English letters, numbers and underscores. You may need to adjust that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.