Get the parent directory of a given file
Solution 1
Assuming
$ file=./Tools/build.bat
With a POSIX compatible shell (including zsh):
$ echo "${file%/*}"
./Tools
With dirname
:
$ echo "$(dirname -- "$file")"
./Tools
(at least GNU dirname
takes options, so the --
is required in case the path starts with a dash.)
Solution 2
If you are using zsh
try :h
modifier
cd $file:h
You can add n of them to go n levels up in directory structure.
Solution 3
this is quite simple with the command dirname, just do the folowing:
cd "$(dirname -- "$file")"
now you can even go further on this
file=/home/switch87/.bashrc
cd "$(dirname -- "$file")"
cd "$(dirname -- "$file")"/..
first cd will get you to /home/switch87, the seccond to /home
Solution 4
get the directory of the file in a very general way (when file is known with a relative or absolute pathname, or no path at all):
the_dir="$(cd -P "$(dirname "${filename}")";pwd)"
So to get the parent of that directory:
the_parent_dir="$(cd -P "$(dirname "${filename}")/..";pwd)"
cd -P : print the "real" (physical) path, instead of a path using symbolic links. If you take the -P
out it also works, but you may get a different result ( for exemple: cd / ; ln -s /long/path/here shortcut ; cd shortcut ; pwd
will show you the path: /shortcut
, whereas if you added -P
to cd
you would see /long/path/here
instead)
Solution 5
I prefer to use a combination of readlink
and dirname
.
parent=$(readlink -f "$(dirname "$file")")
cd $parent
dirname
cuts the filename from the path and readlink -f
turns $path/..
into a canonical path.
Related videos on Youtube
Tim
Elitists are oppressive, anti-intellectual, ultra-conservative, and cancerous to the society, environment, and humanity. Please help make Stack Exchange a better place. Expose elite supremacy, elitist brutality, and moderation injustice to https://stackoverflow.com/contact (complicit community managers), in comments, to meta, outside Stack Exchange, and by legal actions. Push back and don't let them normalize their behaviors. Changes always happen from the bottom up. Thank you very much! Just a curious self learner. Almost always upvote replies. Thanks for enlightenment! Meanwhile, Corruption and abuses have been rampantly coming from elitists. Supportive comments have been removed and attacks are kept to control the direction of discourse. Outright vicious comments have been removed only to conceal atrocities. Systematic discrimination has been made into policies. Countless users have been harassed, persecuted, and suffocated. Q&A sites are for everyone to learn and grow, not for elitists to indulge abusive oppression, and cover up for each other. https://softwareengineering.stackexchange.com/posts/419086/revisions https://math.meta.stackexchange.com/q/32539/ (https://i.stack.imgur.com/4knYh.png) and https://math.meta.stackexchange.com/q/32548/ (https://i.stack.imgur.com/9gaZ2.png) https://meta.stackexchange.com/posts/353417/timeline (The moderators defended continuous harassment comments showing no reading and understanding of my post) https://cs.stackexchange.com/posts/125651/timeline (a PLT academic had trouble with the books I am reading and disparaged my self learning posts, and a moderator with long abusive history added more insults.) https://stackoverflow.com/posts/61679659/revisions (homework libels) Much more that have happened.
Updated on September 18, 2022Comments
-
Tim over 1 year
Suppose
file
stores the pathname of a non-dir file.How can I get its parent directory?
why does the following way by appending
/..
to its value not work$ cd $file/.. cd: ./Tools/build.bat/..: No such file or directory
Thanks.
-
schaiba about 7 yearsExample of such a pathname?
-
ivanivan about 7 yearsdirname may be what you want
-
Tim about 7 years@schaiba
./Tools/build.bat
as in the example -
Sahil Chaudhary about 7 yearsDo you ever search before asking or ask basic questions just for the upvotes? It's hard to believe you couldn't find this doing a little searching.
-
-
Stéphane Chazelas about 7 yearsAlso works in
csh
/tcsh
where it comes from though in those shells, you'll need to add a:q
to account for directory names that contain blanks or wildcards. -
Tim about 7 yearsThanks. why does the following way by appending /.. to its value not work
-
Tim about 7 yearsokay, I see it is because $file isn't a directory
-
gardenhead about 7 yearsDo you really need the
echo
? -
Pysis about 7 yearsJust a note: I use
dirname
all the time, as I find it more expressive. -
ilkkachu about 7 years@gardenhead, only for demonstration. Of course really we'd just do
somecommand "${file%/*}"
(And even for printing,printf
would arguably be better.) -
Gilles 'SO- stop being evil' about 7 yearsThat potentially gives a different path to the directory, which may not be desirable.