Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to get just the name of the parent directory for a file.

Example: When I have path=/a/b/c/d/file, I want only d and not /a/b/c/d (which I get from dirname $path) as output.

Is there any sophisticated way to do this?

share|improve this question

It sounds like you want the basename of the dirname:

$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d
share|improve this answer
    
why am I receiving . instead of the parent directory on debian? – Amir Nov 10 '15 at 10:17
    
@Amir: Are you starting with a full path, or just a filename? If it's just a filename, the dirname command will assume it's in the current directory (aka "."). – Gordon Davisson Nov 10 '15 at 15:09
    
well, I am using this: parentname="$(basename "$(dirname "$pwd")")" – Amir Nov 10 '15 at 15:33
1  
@Amir: Shell variables are case sensitive, and PWD must be capitalized. Try parentname="$(basename "$(dirname "$PWD")")". – Gordon Davisson Nov 10 '15 at 17:31

You can use pwd to get the current working directory, and use parameter expansion to avoid forking it into another (sub)shell.

echo ${PWD##*/}

Edit: proven source

share|improve this answer
    
The question has nothing to do with the current directory. You could use ${path##*/} – Matteo Jan 20 '13 at 9:22

I think this is a less-resource solution:

 $ filepath=/a/b/c/d/file
 $ echo ${${filepath%/*}##*/}
 d

edit: Sorry, nested expansion isn't possible in bash, but it works in zsh. Bash-version:

 $ filepath=/a/b/c/d/file
 $ path=${filepath%/*}
 $ echo ${path##*/}
 d
share|improve this answer
    
There are some edge cases this doesn't handle well, mainly when there isn't a full multilevel path. For example, try it with filepath=file or filepath=/file`. – Gordon Davisson Jan 20 '13 at 22:31
    
Indeed. But what is the parent directory of foofile? If it isn't full path can't know (maybe if foofile is an existing file not only a "string"). – uzsolt Jan 21 '13 at 8:54

In bash, in one line:

$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,'
share|improve this answer
    
can you please elaborate the procedures involved? it can be of help to future readers. also, please try not to write 1/2 line answers. – Lorenzo Von Matterhorn Apr 28 '13 at 19:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .