I have the path /home/bamboo/bamboo-agent-home/xml-data/build-dir/NG-VOSGQL239-JOB1
and would like to get just /home/bamboo/bamboo-agent-home/xml-data/build-dir/
How can I delete the last part of the path if it can be with different lengths by using Bash?
Asked
Active
Viewed 137 times
0

James Brown
- 36,089
- 7
- 43
- 59

Ihor Pysmennyi
- 39
- 1
- 5
-
You could try parameter expansion here like `val="/home/bamboo/bamboo-agent-home/xml-data/build-dir/NG-VOSGQL239-JOB1" ; echo ${val%/*}`. – RavinderSingh13 Mar 19 '19 at 14:53
-
1Why is python listed in the tags? – Paul Hodges Mar 19 '19 at 16:18
-
Possible duplicate of [Remove part of path on Unix](https://stackoverflow.com/q/10986794/608639), [How to remove end folder name from a path in Linux script?](https://stackoverflow.com/q/29329093/608639), etc. – jww Mar 20 '19 at 01:49
3 Answers
3
Some common ways to do that are:
$ str=/home/bamboo/bamboo-agent-home/xml-data/build-dir/NG-VOSGQL239-JOB1
$ echo "${str%/*}" # fast, but wrong if str has no "/"s in it
/home/bamboo/bamboo-agent-home/xml-data/build-dir
$ dirname "$str" # slow, but returns "." for bare names
/home/bamboo/bamboo-agent-home/xml-data/build-dir
$ echo "$str" | sed 's@/[^/]*$@@' # more general, but slow *and* wrong with no "/"s
/home/bamboo/bamboo-agent-home/xml-data/build-dir
Note, in the above, we use "wrong" to indicate unexpected behavior in the case of path manipulation. (eg, we define the output of dirname
to be the correct behavior.)

William Pursell
- 204,365
- 48
- 270
- 300
-
2I wouldn't recommend using `sed`; you are just reimplementing `dirname` with no upside. (`dirname` is just as much part of POSIX as `sed` is.) – chepner Mar 19 '19 at 14:59
-
Agree that `sed` is the wrong tool for this case. But `echo | sed ...` is a common idiom for string manipulation, and can be generalized. – William Pursell Mar 19 '19 at 15:02
2
Use dirname
dirname /home/bamboo/bamboo-agent-home/xml-data/build-dir/NG-VOSGQL239-JOB

Sarath Sadasivan Pillai
- 6,737
- 29
- 42
-
2The one reason to prefer `dirname` over the parameter expansion `"${s%/*}"` is that dirname returns `.` if there are no `/`s in a filename at all. That's sometimes a compelling difference, but you take a big performance hit to `fork()` a subprocess and then load and execute an external command on behalf of that difference. – Charles Duffy Mar 19 '19 at 15:03
2
Using bash regex =~
:
$ var=/home/bamboo/bamboo-agent-home/xml-data/build-dir/NG-VOSGQL239-JOB
$ [[ $var =~ .*/ ]] && echo "${BASH_REMATCH[0]}"
/home/bamboo/bamboo-agent-home/xml-data/build-dir/

James Brown
- 36,089
- 7
- 43
- 59
-
2`if [[ $var =~ (.*)/ ]]; then echo "${BASH_REMATCH[1]}"; else echo .; fi` would be a more complete emulation of basename behavior. – Charles Duffy Mar 19 '19 at 15:08