This post was originally published on go2linux.org on February 24, 2008. The domain is no longer mine, but I am the original author. I am republishing it here on garron.me with corrections and improvements.
Introduction
basename strips the directory path from a file name, and optionally removes a trailing suffix. It is part of GNU Coreutils and is available on every Linux system.
It is most useful inside shell scripts where you need only the file name from a full path.
Syntax
basename NAME [SUFFIX]
basename OPTION... NAME...
Basic examples
Strip the directory from a path:
basename /usr/bin/sort
Output: sort
Strip both the directory and a suffix:
basename include/stdio.h .h
Output: stdio
Strip a .tar.gz extension:
basename /home/ggarron/backups/archive.tar.gz .tar.gz
Output: archive
Multiple names at once
With the -a flag, you can pass multiple names:
basename -a /usr/bin/sort /usr/bin/ls /usr/bin/cat
Output:
sort
ls
cat
Use a custom suffix separator
With -s, you specify a suffix and can pass multiple names:
basename -s .txt /home/user/doc1.txt /home/user/doc2.txt
Output:
doc1
doc2
In shell scripts
basename is most commonly used in scripts to extract the file name from $0 (the script's path) or from a loop variable.
Get the script's own name for error messages:
#!/bin/bash
SCRIPTNAME=$(basename "$0")
echo "$SCRIPTNAME: error: something went wrong" >&2
Rename files by stripping a suffix and adding a new one:
for f in /var/log/*.log; do
name=$(basename "$f" .log)
cp "$f" "/tmp/${name}.bak"
done
Process files in a loop without the directory prefix:
for f in /etc/cron.d/*; do
echo "Cron job: $(basename "$f")"
done
dirname — the complement to basename
dirname does the opposite: it strips the file name and returns the directory.
dirname /usr/bin/sort
Output: /usr/bin
Together they let you split a path into its two components:
path=/etc/apt/sources.list
dir=$(dirname "$path") # /etc/apt
file=$(basename "$path") # sources.list
Always quote your variables
When file names may contain spaces, quote the argument to avoid word splitting:
basename "$f" # correct
basename $f # breaks on spaces
See also
dirname— return the directory portion of a pathreadlink -f— resolve a path to its absolute formrealpath— similar to readlink -f, available on modern systems