strip version from package name using Bash
Asked Answered
P

4

7

I'm trying to strip the version out of a package name using only Bash. I have one solution but I don't think that's the best one available, so I'd like to know if there's a better way to do it. by better I mean cleaner, easier to understand.

suppose I have the string "my-program-1.0" and I want only "my-program". my current solution is:

#!/bin/bash

PROGRAM_FULL="my-program-1.0"
INDEX_OF_LAST_CHARACTER=`awk '{print match($0, "[A-Za-z0-9]-[0-9]")} <<< $PROGRAM_FULL`
PROGRAM_NAME=`cut -c -$INDEX_OF_LAST_CHARACTER <<< $PROGRAM_FULL`

actually, the "package name" syntax is an RPM file name, if it matters.

thanks!

Pulmonary answered 24/5, 2010 at 17:44 Comment(4)
how about run it thought sed "s/[-0-9.]*$//" ?Indivertible
@BCS: Or something a little more careful; yours matches against program-name-3...4--789, for example, or more realistically, against program-name2-1.0 (incorrectly stripping the 2 as well).Marleah
Do note that the version may have letters in it as well.Inkster
What do you mean by "using only Bash"? The solution you propose uses awk and cut (it is seldom necessary to use cut, as awk is sufficient). Are you trying to eliminate all such tools?Matchbook
M
9

Pretty well-suited to sed:

# Using your matching criterion (first hyphen with a number after it
PROGRAM_NAME=$(echo "$PROGRAM_FULL" | sed 's/-[0-9].*//')

# Using a stronger match
PROGRAM_NAME=$(echo "$PROGRAM_FULL" | sed 's/-[0-9]\+\(\.[0-9]\+\)*$//')

The second match ensures that the version number is a sequence of numbers separated by dots (e.g. X, X.X, X.X.X, ...).

Edit: So there are comments all over based on the fact that the notion of version number isn't very well-defined. You'll have to write a regex for the input you expect. Hopefully you won't have anything as awful as "program-name-1.2.3-a". Absent any additional request from the OP though, I think all the answers here are good enough.

Marleah answered 24/5, 2010 at 17:51 Comment(10)
Might want to test the second version. ;-)Huckleberry
@Jon Ericson: I did. Works as expected for name-X, name-XX, name-X.X, name-X.X.X, and assorted other permutations. It refuses to replace anything that's not a properly formatted version number, like name-X.. Is that not the desired behavior?Marleah
On my box: $ echo my-program-1.0 | sed 's/-[0-9]\+\(\.[0-9]\+\)*$//' produces my-program-1.0 According to the documentation, sed does not support the + syntax.Huckleberry
@Jon Ericson: Whoa. What system is that?Marleah
I tried both on Solaris and Linux. There might be a setting to turn on Perl style REs on Linux that I don't have set.Huckleberry
@Jon Ericson: It's not perl style - you don't have to escape the + in perl. And... well, here's what I know. Right now I only have access to a CentOS 5 box, and its sed says that it essentially supports POSIX.2 BREs, and the documentation for those definitely mentions +. It's pretty, well, basic.Marleah
@Jon Ericson: I hate to suggest this, but you couldn't have botched the quoting, so that the \+ turned into a + before it got to sed?Marleah
the second version is a nice enforcing expression, but that won't work for me as I'm dealing with RPM file names (for example, alsa-lib-1.0.17-1.el5.i386.rpm). removing everything after the first hyphen with a number after it will do it :-)Pulmonary
@Jon: You probably need to escape the parentheses or use the -r option. For me, with GNU sed 4.2.1, echo my-program-1.0 | sed 's/-[0-9]\+\(\.[0-9]\+\)*$//' works, as does sed -r 's/-[0-9]+(\.[0-9]+)*$//'Bituminous
Crap. I take back the Linux comment. uname reveals I was on another SunOS system. Sorry for the noise.Huckleberry
B
4

Bash:

program_full="my-program-1.0"
program_name=${program_full%-*}    # remove the last hyphen and everything after

Produces "my-program"

Or

program_full="alsa-lib-1.0.17-1.el5.i386.rpm"
program_name=${program_full%%-[0-9]*}    # remove the first hyphen followed by a digit and everything after

Produces "alsa-lib"

Bituminous answered 24/5, 2010 at 18:53 Comment(2)
The first is correct since it takes advantage of the fact that the version can never have a hyphen. The second is not since parts of the name can start with a digit.Inkster
@Ignacio: True, it would have to be a name like "abc-2def-1.0.42-2.foo.i286.rpm" which would incorrectly become "abc".Bituminous
H
1

How about:

$ echo my-program-1.0 | perl -pne 's/-[0-9]+(\.[0-9]+)+$//'
my-program
Huckleberry answered 24/5, 2010 at 17:51 Comment(4)
Nitpicky details: this will match against program-. but not program-1.2.3.Marleah
@Jefromi: Not any more. ;-) Perl's RE syntax looks much nicer.Huckleberry
Yeah, perl >> sed. Was just trying to keep things simple... +1.Marleah
can we have a stunt that also matches my-program-2-3-4 and the likes of a52dec-0.7.4-15.fc11.i586 aalib-libs-1.4.0-0.18.rc5.fc12.i686 abrt-1.1.14-1.fc13.i686 abrt-addon-ccpp-1.1.14-1.fc13.i686 abrt-addon-kerneloops-1.1.14-1.fc13.i686 abrt-addon-python-1.1.14-1.fc13.i686Slapstick
N
0
echo pkg_name | sed 's/-[^-]*-[^-]*\.[^.]*\.[^.]*$//'

When the full package name is passed in place of pkg_name, it removes the version and gives only the package name.

Normie answered 9/8, 2024 at 13:27 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.