Get the parent directory for a file
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?
6 Answers
It sounds like you want the basename of the dirname:
$ filepath=/a/b/c/d/file
$ parentname="$(basename "$(dirname "$filepath")")"
$ echo "$parentname"
d 4 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
1I think this is a less-resource solution:
$ filepath=/a/b/c/d/file $ echo ${${filepath%/*}##*/} dedit: 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 2 In bash, in one line:
$ dirname /a/b/c/d/file | sed 's,^\(.*/\)\?\([^/]*\),\2,' 4 I like Julian67's answer above best, but here is a bit an expanded version:
file_path = "a/b/c/d/file.txt"
parent=$(echo $file_path | sed -e 's;\/[^/]*$;;') # cut away "/file.txt";'$' is end of string
parent=$(echo $parent | sed -e 's;.*\/;;') # cut away "/a/b/c/"
echo $parent # --> you get "d" 1 dirname and basename should be used for this task.
The short answer is
dirname /a/b/c/d/file | xargs basename
=> dThe first step, getting the dirname of the path, yields the path of the parent folder, as seen below.
dirname /a/b/c/d/file
=> /a/b/c/dThe path of the parent folder is then piped to another command with |. Since basename (and dirname) don't run on streams and instead just on parametized inputs, you cannot directly pipe the results to basename with | basename. This however is fixed by xargs, which turns the stream from the pipe into an input for basename
This allows the final solution to become
dirname /a/b/c/d/file | xargs basenameWhich could also be written as ...
echo '/a/b/c/d/file' | xargs dirname | xargs basename