Derek Dahmer
Derek Dahmer

Reputation: 15485

Get current directory or folder name (without the full path)

How could I retrieve the current working directory/folder 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.

Upvotes: 1177

Views: 1003971

Answers (24)

ahmnouira
ahmnouira

Reputation: 3391

Just run the following command line:

basename $(pwd)

If you want to copy that name:

basename $(pwd) | pbcopy

Or using xclip command if it is installed:

basename $(pwd) | xclip -selection clipboard

enter image description here

Upvotes: 10

Charles Duffy
Charles Duffy

Reputation: 295252

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 is / (root)

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

Upvotes: 1527

Praxder
Praxder

Reputation: 2749

Here's a simple alias for it:

alias name='basename $( pwd )'

After putting that in your ~/.zshrc or ~/.bashrc file and sourcing it (ex: source ~/.zshrc), then you can simply run name to print out the current directories name.

Upvotes: 2

D3M0N
D3M0N

Reputation: 41

An alternative to basname examples

pwd | grep -o "[^/]*$"

OR

pwd | ack -o "[^/]+$"

My shell did not come with the basename package and I tend to avoid downloading packages if there are ways around it.

Upvotes: 1

Benjamin Zach
Benjamin Zach

Reputation: 1601

Just 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

Upvotes: 0

geckos
geckos

Reputation: 6279

There 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}'

Upvotes: 6

abc
abc

Reputation: 3551

Use:

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.

Upvotes: 34

Gautam Sreekumar
Gautam Sreekumar

Reputation: 564

If 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.

Ref: https://superuser.com/questions/60555/show-only-current-directory-name-not-full-path-on-bash-prompt

Upvotes: 3

Arkady
Arkady

Reputation: 15069

Use the basename program. For your case:

% basename "$PWD"
bin

Upvotes: 580

Steve Benner
Steve Benner

Reputation: 1717

I strongly prefer using gbasename, which is part of GNU coreutils.

Upvotes: 2

user2208522
user2208522

Reputation: 51

For the find jockeys out there like me:

find $PWD -maxdepth 0 -printf "%f\n"

Upvotes: 5

Abhishek Gurjar
Abhishek Gurjar

Reputation: 7476

Below grep with regex is also working,

>pwd | grep -o "\w*-*$"

Upvotes: 3

Dutch Glory
Dutch Glory

Reputation: 26273

i 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 ...

Upvotes: 5

Arton Dorneles
Arton Dorneles

Reputation: 1709

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.

Upvotes: 7

Orange
Orange

Reputation: 235

How about grep:

pwd | grep -o '[^/]*$'

Upvotes: 21

mbelos
mbelos

Reputation: 513

You can use a combination of pwd and basename. E.g.

#!/bin/bash

CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`

echo "$BASENAME"

exit;

Upvotes: 37

DigitalRoss
DigitalRoss

Reputation: 146043

$ echo "${PWD##*/}"

​​​​​

Upvotes: 179

marcos
marcos

Reputation: 65

Just use:

pwd | xargs basename

or

basename "`pwd`"

Upvotes: 4

user3278975
user3278975

Reputation: 159

basename $(pwd)

or

echo "$(basename $(pwd))"

Upvotes: 14

anomal
anomal

Reputation: 2299

echo "$PWD" | sed 's!.*/!!'

If you are using Bourne shell or ${PWD##*/} is not available.

Upvotes: 8

niks_4143
niks_4143

Reputation: 97

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>

Upvotes: 0

FDS
FDS

Reputation: 5387

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

Upvotes: 11

rodvlopes
rodvlopes

Reputation: 945

This thread is great! Here is one more flavor:

pwd | awk -F / '{print $NF}'

Upvotes: 14

Paul Sabou
Paul Sabou

Reputation: 3207

The following commands will result in printing your current working directory in a bash script.

pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR

Upvotes: -1

Related Questions