WD_2T
WD_2T

Reputation: 21

Sed invalid range end

I have strings like these:

volume 5

vol. 5

V. 5

v. 5

I'm trying to turn them into this format:

\textbf{5}

with this sed command

s/\(v[a-Z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/

but I keep getting invalid range end. Am I doing something wrong with the 0-9 range?

Upvotes: 2

Views: 2969

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

If you check the ASCII table, you will see that a value is higher than the value of Z. This creates an invalid range. Moreover, you need a case-insensitive pattern, add /I modifier (for GNU sed only):

echo 'volume 5' | sed 's/\(v[a-z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/gI'
echo 'vol. 5' | sed 's/\(v[a-z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/gI'
echo 'V. 5' | sed 's/\(v[a-z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/gI'
echo 'v. 5' | sed 's/\(v[a-z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/gI'

produces

volume \textbf{5}
vol. \textbf{5}
V. \textbf{5}
v. \textbf{5}

Since the BSD implementation of sed does not support case-insensitive matching, on macOS, you need to install GNU sed with the following brew command:

brew install gnu-sed

and then use

gsed -e 's/\(v[a-z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/gI'

etc.

Or, add the uppercase letters to the bracket expression:

sed 's/\(v[a-zA-Z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/g'

And if you want to make sure only ASCII letters are matched add

LC_ALL=C sed 's/\(v[a-zA-Z]*[.]*\) \([0-9]*\)/\1 \\textbf{\2}/g'

Upvotes: 4

Quinn
Quinn

Reputation: 4504

This worked for me:

sed -r "s/([vV][a-zA-Z]*[.]*) ([0-9]*)/\1 \\\textbf{\2}/"

Upvotes: 1

Related Questions