Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting a string between last two slashes in Bash

Tags:

bash

I know this can be easily done using regex like I answered on https://stackoverflow.com/a/33379831/3962126, however I need to do this in bash.

So the closest question on Stackoverflow I found is this one bash: extracting last two dirs for a pathname, however the difference is that if

DIRNAME = /a/b/c/d/e

then I need to extract

d
like image 237
Sasha Avatar asked Oct 27 '15 23:10

Sasha


2 Answers

This may be relatively long, but it's also much faster to execute than most preceding answers (other than the zsh-only one and that by j.a.), since it uses only string manipulations built into bash and uses no subshell expansions:

string='/a/b/c/d/e'  # initial data
dir=${string%/*}     # trim everything past the last /
dir=${dir##*/}       # ...then remove everything before the last / remaining
printf '%s\n' "$dir" # demonstrate output

printf is used in the above because echo doesn't work reliably for all values (think about what it would do on a GNU system with /a/b/c/-n/e).

like image 53
Charles Duffy Avatar answered Sep 22 '22 09:09

Charles Duffy


Here a pure bash solution:

[[ $DIRNAME =~ /([^/]+)/[^/]*$ ]] && printf '%s\n' "${BASH_REMATCH[1]}"

Compared to some of the other answers:

  • It matches the string between the last two slashes. So, for example, it doesn't match d if DIRNAME=d/e.
  • It's shorter and fast (just uses built-ins and doesn't create subprocesses).
  • Support any character between last two slashes (see Charles Duffy's answer for more on this).

Also notice that is not the way to assign a variable in bash:

DIRNAME = /a/b/c/d/e
       ^ ^

Those spaces are wrong, so remove them:

DIRNAME=/a/b/c/d/e
like image 26
whoan Avatar answered Sep 22 '22 09:09

whoan