How would I get just the current working directory name in a bash script, or even better, just a terminal command.
pwd gives the full path of the current working directory, e.g. /opt/local/bin but I only want bin
21 Answers
No need for basename, and especially no need for a subshell running pwd (which adds an extra, and expensive, fork operation); the shell can do this internally using parameter expansion:
result=${PWD##*/} # to assign to a variable result=${result:-/} # to correct for the case where PWD=/ printf '%s\n' "${PWD##*/}" # to print to stdout # ...more robust than echo for unusual names # (consider a directory named -e or -n) printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input # ...useful to make hidden characters readable. Note that if you're applying this technique in other circumstances (not PWD, but some other variable holding a directory name), you might need to trim any trailing slashes. The below uses bash's extglob support to work even with multiple trailing slashes:
dirname=/path/to/somewhere// shopt -s extglob # enable +(...) glob syntax result=${dirname%%+(/)} # trim however many trailing slashes exist result=${result##*/} # remove everything before the last / that still remains result=${result:-/} # correct for dirname=/ case printf '%s\n' "$result" Alternatively, without extglob:
dirname="/path/to/somewhere//" result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim result="${result##*/}" # remove everything before the last / result=${result:-/} # correct for dirname=/ case 31Use the basename program. For your case:
% basename "$PWD" bin 13$ echo "${PWD##*/}"
2Use:
basename "$PWD" OR
IFS=/ var=($PWD) echo ${var[-1]} Turn the Internal Filename Separator (IFS) back to space.
IFS= There is one space after the IFS.
0You can use a combination of pwd and basename. E.g.
#!/bin/bash CURRENT=`pwd` BASENAME=`basename "$CURRENT"` echo "$BASENAME" exit; 4How about grep:
pwd | grep -o '[^/]*$' 1basename $(pwd) or
echo "$(basename $(pwd))" 2This thread is great! Here is one more flavor:
pwd | awk -F / '{print $NF}' I like the selected answer (Charles Duffy), but be careful if you are in a symlinked dir and you want the name of the target dir. Unfortunately I don't think it can be done in a single parameter expansion expression, perhaps I'm mistaken. This should work:
target_PWD=$(readlink -f .) echo ${target_PWD##*/} To see this, an experiment:
cd foo ln -s . bar echo ${PWD##*/} reports "bar"
DIRNAME
To show the leading directories of a path (without incurring a fork-exec of /usr/bin/dirname):
echo ${target_PWD%/*} This will e.g. transform foo/bar/baz -> foo/bar
1echo "$PWD" | sed 's!.*/!!' If you are using Bourne shell or ${PWD##*/} is not available.
Surprisingly, no one mentioned this alternative that uses only built-in bash commands:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}" As an added bonus you can easily obtain the name of the parent directory with:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}" These will work on Bash 4.3-alpha or newer.
2There are a lots way of doing that I particularly liked Charles way because it avoid a new process, but before know this I solved it with awk
pwd | awk -F/ '{print $NF}' For the find jockeys out there like me:
find $PWD -maxdepth 0 -printf "%f\n" 1i usually use this in sh scripts
SCRIPTSRC=`readlink -f "$0" || echo "$0"` RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` echo "Running from ${RUN_PATH}" ... cd ${RUN_PATH}/subfolder you can use this to automate things ...
1Just use:
pwd | xargs basename or
basename "`pwd`" 3Below grep with regex is also working,
>pwd | grep -o "\w*-*$" 1If you want to see only the current directory in the bash prompt region, you can edit .bashrc file in ~. Change \w to \W in the line:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' Run source ~/.bashrc and it will only display the directory name in the prompt region.
I strongly prefer using gbasename, which is part of GNU coreutils.
You can use the basename utility which deletes any prefix ending in / and the suffix (if present in string) from string, and prints the result on the standard output.
$basename <path-of-directory> 0The following commands will result in printing your current working directory in a bash script.
pushd . CURRENT_DIR="`cd $1; pwd`" popd echo $CURRENT_DIR 1Just remove any character until a / (or \, if you're on Windows). As the match is gonna be made greedy it will remove everything until the last /:
pwd | sed 's/.*\///g' In your case the result is as expected:
λ a='/opt/local/bin' λ echo $a | sed 's/.*\///g' bin