4

In a bash shell, I want to take the take a given string that matches a regex, and then take the part of the string.

For example, given https://github.com/PatrickConway/repo-name.git, I want to extract the repo-name substring.

How would I go about doing this? Should I do this all in a shell script, or is there another way to approach this?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Patrick Conway
  • 113
  • 2
  • 5
  • 2
    Do it however you want. Have you made any attempts up to now? – 123 Jun 07 '17 at 19:40
  • 1
    Possible duplicate of [String contains a substring in Bash](https://stackoverflow.com/q/229551/608639). – jww Jun 11 '18 at 00:15

2 Answers2

5

You can use the =~ matching operator inside a [[ ... ]] condition:

#!/bin/bash
url=https://github.com/PatrickConway/repo-name.git
if [[ $url =~ ([^/]*)\.git ]] ; then
    echo "${BASH_REMATCH[1]}"
fi

Each part enclosed in parentheses creates a capture group, the corresponding matching substring can be found in the same position in the BASH_REMATCH array.

  • [...] defines a character class
  • [/] matches a character class consisting of a single character, a slash
  • ^ negates a character class, [^/] matches anything but a slash
  • * means "zero or more times"
  • \. matches a dot, as . without a backslash matches any character

So, it reads: remember a substring of non-slashes, followed by a dot and "git".

Or maybe a simple parameter expansion:

#!/bin/bash
url=https://github.com/PatrickConway/repo-name.git
url_without_extension=${url%.git}
name=${url_without_extension##*/}
echo $name

% removes from the right, # removes from the left, doubling the symbol makes the matching greedy, i.e. wildcards try to match as much as possible.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • Thank you! Fantastic explanation - just what I was looking for. I was trying to use grep with a complex regex...this is much better! – Patrick Conway Jun 08 '17 at 14:21
4

Here's a bashy way of doing it:

var="https://github.com/PatrickConway/repo-name.git"
basevar=${var##*/}
echo ${basevar%.*}

...which gives repo-name

Kind Stranger
  • 1,736
  • 13
  • 18