4

I'm going crazy trying to follow the sed BRE (Basic Regular Expression) rules to replace a pretty simple occurrence in an HTML file.

I think I'm following the spec correctly, but none of my attempts are working.

What I'd like to do is replace the contents of one meta tag with something new (which I'm calculating as part of the script I'm writing). Basically, the meta tag looks like this:

<meta version="v0.103.2" />

It always contains an attribute which follows that syntax, which in a JS regular expression could be characterized as:

/version=\"v[0-9]+\.[0-9]+\.[0-9]+\"/g

So I've tried a whole bunch of sed commands to get this working, and it just doesn't seem to work as documented, unless I'm misunderstanding things. Some of the commands I've tried:

I'm on a Mac (which matters because of sed syntax changes between Unix/Linux), and this accounts for the '' in the commands below.

✗ sed -i -E '' s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\"whatever/g ./src/index.html
✗ sed -i -E '' s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\"whatever/g './src/index.html'
✗ sed -i -E s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\"whatever/g ./src/index.html
✗ sed -i -E s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\whatever/g ./src/index.html
✗ sed -i -E s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\"whatever/g ./src/index.html
✗ sed -i '' s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\"whatever/g ./src/index.html 
✗ sed -i '' s/version=\"v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+/version=\whatever/g ./src/index.html 
✗ sed -i '' s/version=\"v[:digit:]+\.[:digit:]+\.[:digit:]+/version=\whatever/g ./src/index.html 
✗ sed -i '' s/v[:digit:]+\.[:digit:]+\.[:digit:]+/whatever/g ./src/index.html 
✗ sed -i '' s/v[:digit:]+[:punct:][:digit:]+[:punct:][:digit:]+/whatever/g ./src/index.html
✗ sed -i '' s/v[:digit:][:punct:][:digit:][:digit:][:digit:][:punct:][:digit:]+/whatever/g ./src/index.html 
✗ sed -i '' s/v[:digit:][:punct:][:digit:][:digit:][:digit:][:punct:][:digit:]/whatever/g ./src/index.html
✗ sed -i '' s/v[0-9]+\.[0-9]+.[0-9]+/whatever/g ./src/index.html
✗ sed -i '' s/version=\"[^ \"]+\"/whatever/g ./src/index.html
✗ sed -i '' s/version="[^ "]+"/whatever/g ./src/index.html 
✗ sed -i '' s/version=\"[^\"]+\"/whatever/g ./src/index.html 
✗ sed -i '' s/version=/whatever=/g ./src/index.html
✗ sed -i '' s/version=\"/whatever=\'/g ./src/index.html
✗ sed -i '' s/version=\"[^\"]/whatever=\"/g ./src/index.html

Help? It is finding the file correctly. When I try versions of this that don't include a regex (see third from the bottom), it replaces correctly, but somehow my regex syntax seems not to be working here.

Or can anyone think of an easier/more reliable way to do this?

2
  • 1
    Try sed -i '' "s/version=\"v[0-9]*\.[0-9]*\.[0-9]*\"/whatever=/g" ./src/index.html Commented Jun 29, 2017 at 16:27
  • @WiktorStribiżew -- That worked! Want to make it an answer so I can select it? Commented Jun 29, 2017 at 16:28

1 Answer 1

2

You need to quote the regex and instead of + (that is treated as a literal + by the BRE POSIX) use either * (that matches 0 or more occurrences) or \{1,\} range quantifier (in BRE POSIX, the {n,m} must be written as \{m,n\}) that matches 1 or more occurrences.

Thus, you may use

sed -i '' "s/version=\"v[0-9]*\.[0-9]*\.[0-9]*\"/whatever=/g" ./src/index.html

With single quotes:

sed -i '' 's/version="v[0-9]*\.[0-9]*\.[0-9]*"/whatever=/g' ./src/index.html
Sign up to request clarification or add additional context in comments.

2 Comments

Why quote with double quotes and escape double quotes? Can just use single quotes, no need to escape double quotes?
@BenjaminW.: Yes, we can, you are not the first who tells me that, and not the first, or even the second time. I am mostly programming in C#, and am very accustomed to C# string literals that cannot be defined using single quotes. I have started to work with Linux,grep, sed, etc. quite recently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.