1

I'm trying to perform a parameter substitution that strips everything from the first - char to the end of a string like so: v0.1-bla-hblah-232 -> v0.1

So I'm using the following script:

#!/usr/bin/env bash
project_version=$(git describe --tags --long)
clean_version=${project_version%-$}
echo "$project_version"
echo "$clean_version"

If I run this, it does not work:

test λ ./revisioncount.sh
v0.1-2-g2ff1e73
v0.1-2-g2ff1e73

Seems that the $ atom is not being picked up by bash. backslashing it does not work either: \$.

Now if I change the substitution line to this:

clean_version=${project_version%%-*}

Then it works:

test λ ./revisioncount.sh
v0.1-2-g2ff1e73
v0.1

How can I use the $ (which matches the end of the string) to achieve the desired effect?

  • 1
    Two problems: $ matches end of string in many regular expression languages, but not (afaik) in bash parameter substitution patterns. Second, even if it did work, your first pattern is "hyphen followed by end of string, with no characters in between", which would not match any of your strings. – user4556274 Dec 28 '16 at 13:22
  • @user4556274, your absolutely right, thanks. I'd have to use something like -.*$. – ninrod Dec 28 '16 at 14:08
4
clean_version=${project_version%%-*}

is the correct thing to use as you have found out.

% and %% match at the end by definition, so there is no need for an anchor like $ to say match at the end.

For reference # and ## match at the beginning.

The interesting case is the / expansion, which matches anywhere by default. Here the first character being # or % forces the pattern to match at the start or end.

1

The bash idiom ${var%%pattern} use a pattern, not a regular expression.

In a pattern, a .* means something different than your intended "anything".
In fact, a simple * does match a run of any character in a pattern.

Additionally, the % type of match is (by its own nature) delimited by $.

So, this:

echo ${project_version%%-*}

Will match the longest match (%% instead of %) of a dash (-) followed by a run of any character until the end of the string inside project_version.

The correct assignment will be, then:

clean_version=${project_version%%-*}

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.