manuelBetancurt
manuelBetancurt

Reputation: 16168

sed to edit a line on a file

I have a line value I need to update on a file,

export const ADDRESS_ORIGIN = 'chupa-cabra.muz.id';

Im tryging to update with:

sed -i '' 's/ADDRESS_ORIGIN ="[0-9.]*"/ADDRESS_ORIGIN ="'chapuza'"/' constants.js

But the value for

ADDRESS_ORIGIN

Is not updating, I think my REGEX is very wrong, how can I update the value?

Thanks!

Upvotes: 2

Views: 122

Answers (3)

Tyl
Tyl

Reputation: 5262

Why should it?
You missed the space after the equal sign, and double quotes " will literally match double quotes not single quotes ', and [0-9.]* will match consecutive digits and dots.

An alternative to the bewildering quotes alternating would be use ASCII inside the regex:

sed 's/ADDRESS_ORIGIN *= *\x27[^\x27]*\x27/ADDRESS_ORIGIN = \x27chapuza\x27/'

or

sed 's/\(ADDRESS_ORIGIN\) *= *\x27[^\x27]*\x27/\1 = \x27chapuza\x27/'

Or better still, since there could be double quotes around the value, you can consider both situation by this:

sed -E 's/(ADDRESS_ORIGIN) *= *([\x27\x22])[^\039\034]*\2/\1 = \x27chapuza\x27/'

Where \x27 = \039 = ', \x22 = \034 = " in RegEX.

Like this:

$ echo export const ADDRESS_ORIGIN = \"chupa-cabra.muz.id\"\;|sed -E 's/(ADDRESS_ORIGIN) *= *([\x27\x22])[^\039\034]*\2/\1 = \x27chapuza\x27/'
export const ADDRESS_ORIGIN = 'chapuza';

Upvotes: 1

tripleee
tripleee

Reputation: 189908

There is no way "[0-9.]*" can match 'chupa-cabra.muz.id' but without knowing what the permitted values look like we can only speculate. Perhaps '[^']*' would do what you want, though you need to understand the mechanisms of shell quoting in order to correctly get it through to sed. In this particular case, the simplest by far is to use double quotes around the sed script instead of single:

sed -i '' "s/ADDRESS_ORIGIN = *'[^']*'/ADDRESS_ORIGIN = 'chapuza'/" constants.js

though if you know what you are doing, you could also do it with alternating single and double quotes:

sed -i '' 's/ADDRESS_ORIGIN = *'"'[^']*'"'/ADDRESS_ORIGIN = '"'chapuza'/" constants.js

The basic mechanism here is that adjacent strings will be glued together into one string by the shell. So "a"'b' is a a double-quoted a followed by a single-quoted b. After the shell is done parsing it, you get the string ab. Now for fun, imagine that a is a literal single quote, and b is a literal double quote.

... Or perhaps you only want to replace the first token before the dot? Then '[^.']*\. would match and you'd want to replace with 'chapuza. Or use a back reference '[^.']*\(['.]\) and replace with 'chapuza\1

In the general case, of course, double quotes have different semantics than single, so if your script uses characters which will be mangled by the shell when you switch quotes, you need to add a backslash before them, or switch to the "seesaw quoting" mechanism I described above. But in this particular case, your example script doesn't require any modifications to adapt to double quotes.

Upvotes: 2

l'L'l
l'L'l

Reputation: 47284

I assume you are on macOS because of the way you are using in-place editing; this should work:

sed -E -i '' "s@(ADDRESS_ORIGIN = )'.*'@\1'chapuza'@g"

Result:

export const ADDRESS_ORIGIN = 'chapuza';

Upvotes: 1

Related Questions