In my script I need the directory of the file I am working with. For example, the file="stuff/backup/file.zip". I need a way to get the string "stuff/backup/" from the variable $file
.
Asked
Active
Viewed 1e+01k times
155

codeforester
- 39,467
- 16
- 112
- 140

Matt
- 2,790
- 6
- 24
- 34
-
duplicates: [get parent directory of a file in bash](https://stackoverflow.com/q/40700119/995714), [Get the parent directory of a given file](https://unix.stackexchange.com/q/351916/44425), [Getting the parent of a directory in Bash](https://stackoverflow.com/q/8426058/995714) – phuclv Mar 20 '21 at 01:21
-
@phuclv This question was asked on 2011-06-28, before all of those questions linked were posted (2016-11-20, 2017-03-16, and 2011-12-08, respectively). – Edwin Jul 12 '21 at 17:21
-
@Edwin time is irrelevant on SO. [The question with a better set of answers remain open](https://meta.stackoverflow.com/q/251938/995714) – phuclv Jul 13 '21 at 01:33
5 Answers
249
dirname $file
is what you are looking for

Matthieu
- 16,103
- 10
- 59
- 86
-
+1, beat me to it. would have been quicker but was prompoted to enter more than `dirname $file` – matchew Jun 28 '11 at 16:18
-
3`dirname "$file"`, rather. Without the quotes this will misbehave if the file or directory name has spaces. – Charles Duffy Sep 21 '18 at 16:38
-
1fml, the question should be extract absolute dir from file, how do I do that? dirname yields relative path I guess – Alexander Mills Oct 19 '18 at 06:55
-
It is outstanding how difficult this is to accomplish in a win Batch script -- another reason not to use them I suppose! – bunkerdive Apr 22 '20 at 07:08
58
dirname $file
will output
stuff/backup
which is the opposite of basename
:
basename $file
would output
file.zip

the Tin Man
- 158,662
- 42
- 215
- 303

matchew
- 19,195
- 5
- 44
- 48
-
I figured Matt would be able to figure it from there (man dirname) :) – Matthieu Jun 28 '11 at 16:22
-
1I think we are all Matt's here. Just a guess. But I was just trying to distinguish my answer from yours. =) – matchew Jun 28 '11 at 17:29
-
Yeah, I do use basename a lot too, it's very nifty =) But I could just not find anything about returning the file's dir on google! I guess I wasn't looking up the right words. Hah, all 3 of us Matt's? :D – Matt Jun 28 '11 at 19:28
-
1Consider adding the necessary quotes to ensure that these commands work with names containing spaces (glob characters, etc). – Charles Duffy Sep 21 '18 at 16:39
7
Using ${file%/*}
like suggested by Urvin/LuFFy is technically better since you won't rely on an external command. To get the basename in the same way you could do ${file##*/}
. It's unnecessary to use an external command unless you need to.
file="/stuff/backup/file.zip"
filename=${1##*/} # file.zip
directory=${1%/*} # /stuff/backup
It would also be fully POSIX compliant this way. Hope it helps! :-)

MageParts
- 179
- 1
- 1
-
1There is *one* case where `dirname` has an advantage over the (more efficient) built-in approach, and that's if you aren't certain that your path is fully-qualified to start with. If you have `file=file.zip`, `dirname "$file"` will return `.`, whereas `${file%/*}` will return `file.zip`. – Charles Duffy Sep 21 '18 at 16:40
-
1...of course, you can branch: `case $file in */*) dir=${file%/*};; *) dir=.;; esac` is still POSIX-y and addresses the issue. – Charles Duffy Sep 21 '18 at 16:42
2
For getting directorypath
from the filepath
:
file="stuff/backup/file.zip"
dirPath=${file%/*}/
echo ${dirPath}

LuFFy
- 8,799
- 10
- 41
- 59

Urvin Shah
- 61
- 1
- 7
1
Simply use $ dirname /home/~username/stuff/backup/file.zip
It will return /home/~username/stuff/backup/

Nishchay Sharma
- 1,314
- 1
- 9
- 18