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