Cheetah
Cheetah

Reputation: 14379

Capture group from regex in bash

I have the following string /path/to/my-jar-1.0.jar for which I am trying to write a bash regex to pull out my-jar.

Now I believe the following regex would work: ([^\/]*?)-\d but I don't know how to get bash to run it.

The following: echo '/path/to/my-jar-1.0.jar' | grep -Po '([^\/]*?)-\d' captures my-jar-1

Upvotes: 6

Views: 9782

Answers (3)

rici
rici

Reputation: 241721

You can do this as well with shell prefix and suffix removal:

$ path=/path/to/my-jar-1.0.jar
# Remove the longest prefix ending with a slash
$ base="${path##*/}"
# Remove the longest suffix starting with a dash followed by a digit
$ base="${base%%-[0-9]*}"
$ echo "$base"
my-jar

Although it's a little annoying to have to do the transform in two steps, it has the advantage of only using Posix features so it will work with any compliant shell.

Note: The order is important, because the basename cannot contain a slash, but a path component could contain a dash. So you need to remove the path components first.

Upvotes: 4

Jeff Y
Jeff Y

Reputation: 2456

grep -o doesn't recognize "capture groups" I think, just the entire match. That said, with Perl regexps (-P) you have the "lookahead" option to exclude the -\d from the match:

echo '/path/to/my-jar-1.0.jar' | grep -Po '[^/]*(?=-\d)'

Some reference material on lookahead/lookbehind: http://www.perlmonks.org/?node_id=518444

Upvotes: 1

anubhava
anubhava

Reputation: 785146

In BASH you can do:

s='/path/to/my-jar-1.0.jar'

[[ $s =~ .*/([^/[:digit:]]+)-[[:digit:]] ]] && echo "${BASH_REMATCH[1]}"

my-jar

Here "${BASH_REMATCH[1]}" will print captured group #1 which is expression inside first (...).

Upvotes: 5

Related Questions