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 9.1k times
139
codeforester
- 34,080
- 14
- 96
- 122
Matt
- 2,552
- 6
- 22
- 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
230
dirname $file
is what you are looking for
Matthieu
- 15,687
- 10
- 58
- 85
-
+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
-
2`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
53
dirname $file
will output
stuff/backup
which is the opposite of basename:
basename $file
would output
file.zip
the Tin Man
- 155,156
- 41
- 207
- 295
matchew
- 18,350
- 4
- 42
- 46
-
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
5
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
- 159
- 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
- 7,689
- 10
- 38
- 58
Urvin Shah
- 41
- 1
- 6
1
Simply use $ dirname /home/~username/stuff/backup/file.zip
It will return /home/~username/stuff/backup/
Nishchay Sharma
- 1,274
- 1
- 9
- 16