Linux basename Command: Extract the Final Component of a Path

`basename` is a command that removes the directory part from a path string and outputs only the final file name or directory name. Optionally, it can also remove a suffix at the end of the file name, making it useful in shell scripts when converting a path into a display name.

`basename` is not a command to open files or check the existence of a path. It processes the input string, so it can be used on paths that do not exist.

What is the basename command?

Use `basename` when you only need the last component of a path.

basename /home/user/report.txt

The output is as follows.

report.txt

It does not matter whether the input path is a file or a directory. It returns the last name after removing the trailing slash.

Basic Syntax and Usage

basename name [suffix]
basename options name...

A basic usage example is as follows.

basename /var/log/nginx/access.log
basename /home/user/Documents/
basename relative/path/file.txt

Each result is `access.log`, `Documents`, and `file.txt`. Any unnecessary trailing slashes are removed, but special inputs like the root path are handled separately.

Removing Suffixes

Specifying a Suffix with the Second Argument

If you specify a suffix after the name, it will be removed when the last name ends with that string.

basename /data/archive.tar.gz .gz
basename /home/user/report.txt .txt

The output is archive.tar and report, respectively. To remove the entire .tar.gz, specify the entire string to be removed.

basename /data/archive.tar.gz .tar.gz

Removing Suffixes from Multiple Names with -s

The GNU basename -s or --suffix option specifies the suffix as an option. Using this option also activates the -a behavior to process multiple names together.

basename -s .jpg /images/a.jpg /backup/b.jpg
basename --suffix=.log /var/log/app.log /tmp/test.log

If the suffix does not match, the original last name is printed as is. The suffix is a string compared literally, not a regex.

Processing Multiple Paths

Process multiple names with -a

Using -a or --multiple allows you to process multiple paths at once and outputs each result on a separate line.

basename -a /srv/www/index.html /var/log/syslog /home/user

The output takes the following form.

index.html
syslog
user

Separate with NUL using -z

File names can include newline characters. To avoid ambiguity in automation, you can output NUL characters instead of newlines at the end of each result using -z or --zero.

basename -z -a /data/file1 /data/file2

The following command that produces NUL-delimited output should support the same format. It is a feature meant for safe inter-program transmission, not an option for checking directly on the screen.

Comparing basename and dirname

Input basename dirname
/home/user/report.txt report.txt /home/user
docs/manual.pdf manual.pdf docs
notes.txt notes.txt .
/ / /

These two commands are convenient when splitting path strings complementarily. However, simply reconnecting the two outputs with a slash may not result in an identical string to the original due to duplicate slashes or special inputs.

Handling file extensions

Removing known extensions

If the extensions to remove are fixed, using the suffix argument is a clear method.

basename photo.webp .webp
basename backup.tar.gz .tar.gz

This method only removes the extension when the ending exactly matches, so in report.txt.bak, .txt will not be removed.

Not automatically considering everything after the last dot as an extension

Just because a file name has a dot does not mean it always has an extension. There are hidden files starting with a dot like .profile, files with multiple suffixes like archive.tar.gz, and names that end with a dot.

Clearly define the suffixes to remove according to your work rules, and be careful when simply deleting everything after the last dot.

Using in shell scripts

Getting the Display Filename from a Path

path='/srv/uploads/annual report.pdf'
name=$(basename -- "$path") || exit 1
printf 'Filename: %s\n' "$name"

-- causes the following string to be treated as a name rather than an option. This is useful when dealing with inputs that can start with a hyphen, and it's always safe to enclose variables in double quotes.

Comparing with POSIX Shell Parameter Expansion

If you only need the last part of a path inside the shell, you can also use parameter expansion instead of external commands.

path='/srv/uploads/report.pdf'
name=${path##*/}
printf '%s\n' "$name"

However, if the path ends with a slash or is a root path, the result may differ from basename. If the input format is not controlled, do not assume that your custom string rules behave the same as basename.

Summary of major options

Option Description
-a, --multiple Handle multiple names and output each result.
-s suffix, --suffix=suffix Removes the specified suffix from the end of each name and also enables handling multiple names.
-z, --zero End each result with a NUL character instead of a newline.
--help Displays usage and supported options.
--version Prints the installed GNU Coreutils version.

Options like -a, -s, and -z are GNU extensions. If you are writing scripts to run on various Unix-like systems, check the implementation on the target system and prioritize the standard format defined by POSIX.

Common issues

Results are printed even if the file does not exist

This is normal behavior. basename extracts the last part from the input string without checking for the file's existence. If the operation requires an actual file, you should separately check for existence and permissions.

Paths with spaces are split into multiple arguments

If you do not enclose variables in double quotes, shell word splitting and glob expansion may occur.

basename -- "$path"

Suffix not removed

The suffix must exactly match the end of the last name. It is case-sensitive and is not interpreted as a regular expression or wildcard.

FAQ

Does basename rename the actual file?

No. It only calculates and outputs the last name from the input path string without changing any files or directories.

Can basename remove an extension?

You can specify the suffix to remove as the second argument, like basename path.txt. In a GNU environment, to handle multiple names, you can use basename -s.txt name....

Does basename work on a non-existent path?

Yes. Because it only processes the path string, it outputs the last component even if the actual file does not exist.

What is the difference from dirname?

basename outputs the last name, while dirname outputs the directory part excluding the last name.

Related articles and official documentation

More in This Category
Linux rmdir Command: Remove Empty Directories

Linux rmdir Command: Remove Empty Directories

Learn how to remove empty directories with Linux rmdir, delete empty parent paths, diagnose failures, and understand when rm -r is different.

Linux gzip Command: Compress a File in gzip Format

Linux gzip Command: Compress a File in gzip Format

Learn how to compress a File in gzip Format with the Linux gzip command, including practical examples, key options, and important precautions.

Linux history Command: Review and Reuse Shell Command History

Linux history Command: Review and Reuse Shell Command History

Learn how to use the Linux history command to review, search, reuse, and manage shell command history, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux whereis Command: Locate Binaries, Source, and Man Pages

Linux whereis Command: Locate Binaries, Source, and Man Pages

Learn how Linux whereis locates binaries, source files, and manual pages, limits each search type, lists effective paths, and differs from which and find.

Linux chgrp Command: Change a File's Group

Linux chgrp Command: Change a File's Group

Learn how to change a File's Group with the Linux chgrp command, including practical examples, key options, and important precautions.

Linux nc Command: Test TCP and UDP Connections

Linux nc Command: Test TCP and UDP Connections

Learn how to test TCP and UDP Connections with the Linux nc command, including practical examples, key options, and important precautions.

Linux chown Command: Change File Owner and Group

Linux chown Command: Change File Owner and Group

Learn how to change File Owner and Group with the Linux chown command, including practical examples, key options, and important precautions.

Linux dd Command: Copy and Convert Data by Blocks

Linux dd Command: Copy and Convert Data by Blocks

Learn how to copy and convert files or block devices with Linux dd, choose block sizes and ranges, display progress, verify results, and avoid overwriting the wrong device.

Linux blkid Command: Find Block-Device UUIDs and Filesystem Types

Linux blkid Command: Find Block-Device UUIDs and Filesystem Types

Learn how to find Block-Device UUIDs and Filesystem Types with the Linux blkid command, including practical examples, key options, and important precautions.

Linux killall Command: Signal Processes by Name

Linux killall Command: Signal Processes by Name

Learn how to signal Processes by Name with the Linux killall command, including practical examples, key options, and important precautions.