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!

cd1
  • 15,908
  • 12
  • 46
  • 47

3 Answers3

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.

Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • 1
    Might want to test the second version. ;-) – Jon 'links in bio' Ericson May 24 '10 at 17:57
  • @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? – Cascabel May 24 '10 at 18:10
  • 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. – Jon 'links in bio' Ericson May 24 '10 at 18:14
  • @Jon Ericson: Whoa. What system is that? – Cascabel May 24 '10 at 18:24
  • 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. – Jon 'links in bio' Ericson May 24 '10 at 18:27
  • @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. – Cascabel May 24 '10 at 18:31
  • @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? – Cascabel May 24 '10 at 18:32
  • 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 :-) – cd1 May 24 '10 at 18:37
  • @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]+)*$//'` – Dennis Williamson May 24 '10 at 18:44
  • Crap. I take back the Linux comment. `uname` reveals I was on another SunOS system. Sorry for the noise. – Jon 'links in bio' Ericson May 24 '10 at 19:27
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"

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
1

How about:

$ echo my-program-1.0 | perl -pne 's/-[0-9]+(\.[0-9]+)+$//'
my-program
Jon 'links in bio' Ericson
  • 20,880
  • 12
  • 98
  • 148
  • Nitpicky details: this will match against `program-.` but not `program-1.2.3`. – Cascabel May 24 '10 at 17:54
  • @Jefromi: Not any more. ;-) Perl's RE syntax looks much nicer. – Jon 'links in bio' Ericson May 24 '10 at 18:21
  • Yeah, perl >> sed. Was just trying to keep things simple... +1. – Cascabel May 24 '10 at 18:25
  • 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.i686`` – nyxee Aug 15 '17 at 07:56