How to Use Bash basename Command to Extract Filenames

As a developer, you need filenames and their extensions to perform various operations on them. In Linux, the basename command extracts the file or directory name from a path. 

In this guide, I will explore the basename command: its basic and advanced usage in bash scripting. Moreover, I will also shed light on alternative methods to extract filenames in bash.

Table of Contents:

  1. Bash basename Command Syntax
  2. How does Bash basename Command Work
  3. How to Extract Filenames from Multiple Paths
  4. How do I Get All the Filenames from a Directory
  5. How do I Remove Extensions from Basename
  6. How to Deal Paths with Spaces
  7. Limitations of basename Command
  8. How do I use basename with find Command 
  9. Alternative Methods to Get the Filenames in Bash

Bash basename Command Syntax

To get the filename, use the file path with the basename command.

The syntax is as follows:

basename [PATH]

Similarly, the syntax of the basename command to extract the filename without the extension suffix is given below:

basename [PATH] [SUFFIX]

How does Bash basename Command Work

The basename command essentially removes the entire path and keeps the name whether it is a file or a directory after the last slash (/).

Here is a simple example:

The return of the basename command solely depends upon the path.

Pathbasename
/home/ilf/dir/file.txtfile.txt
/home/ilf/dir/dir
/home/ilfilf
/homehome
//
..
....

How to Extract Filenames from Multiple Paths

To extract filenames from multiple paths, use the -a flag with the basename command and paths.

basename -a [PATH1] [PATH2]

If you want to remove the suffixes from filenames use the -s flag with the suffix.

basename -a -s [SUFFIX] [PATH1] [PATH2] .. [PATHN]

Note that you cannot use multiple suffixes. So, if filenames have different suffixes, then only the mentioned suffix will be removed.

How do I Get All the Filenames from a Directory

If you need to analyze data from multiple files within a directory, you might need to retrieve all the filenames from that directory.

The given shell script extracts the filenames from a directory using a for loop and basename command.

#!/bin/bash
for files in /home/ilf/dir/*do echo "The path of all files: $files" filenames=$(basename "$files") echo $filenamesdone

In the code, the files variable iterates through all the files in the directory and grabs the paths. Then the basename command extracts the filenames through the file paths assigned to the files variable.

How do I Remove Extensions from Basename

Many files typically process based on their content rather than file types. In such scenarios, you may need filenames without file extensions. To remove the file extension using the basename command, simply add the extension at the end of the path. 

For example, to remove the .txt extension, use the following command.

basename /home/ilf/dir/file1.txt .txt

Let’s implement it in the bash script.

#!/bin/bash
for files in /home/ilf/dir/*do echo "The path of all files: $files" filenames=$(basename "$files" .txt) echo $filenamesdone

The output image shows the filenames are populated without .txt extensions. 

Note that if you do not mention the dot (.), only the txt will be removed and the dot will remain attached.

How to Deal Paths with Spaces

In the above examples, the paths are simple without any spaces. To deal with the paths with spaces, simply use the path in quotations (“”).

basename "[PATH WITH SPACES]"

Limitations of basename Command

The basename command is the easiest way to extract the file names from paths. However, it also has limitations.

Designed for String Manipulation

The basename utility is purely designed with string manipulation tools, so compared to tools like awk and sed it is less smart.

No Wildcard Compatibility

basename does not support the wildcard, hence cannot process multiple paths directly.

No Recursive Capability 

There is no direct capability of recursion with the basename command.

How do I use basename with find Command 

To get more out of the basename, it can be used with find, or xargs commands. 

For instance, to extract all filenames in a directory, the combination of the find and basename commands can be used.

find [PATH] -type f -exec basename { } \;

The -exec is used to execute the external command with the find command, while { } is storing the filenames, and \; is indicating the end of the -exec command.

In the above image, it can be seen that the find command prints the entire path with filenames. However, if we use basename with find, then the exact filenames are extracted.

Alternative Methods to Get the Filenames in Bash

Some other tools that can be used to extract the filenames from paths are:

  • Bash Parameter Expansion
  • awk
  • sed 

Get Filename using Bash Parameter Expansion

Bash parameter expansion is a handy way to extract the filename from a path. Let’s understand it with an example script.

path=/home/ilf/dir/file1.txtecho ${path##*/}

In the above script, the file path is assigned to a variable path and then the filename is printed using echo. The ${path##*/} is parameter expansion, where */ matches any sequence of characters followed by slash (/). The ## removes the longest match of the specified pattern from the beginning. 

You can also create an array of paths to get filenames from multiple paths.

Get Filename using awk

The awk is a text processing language and a powerful tool for data extraction. The command to get the filename using awk is as follows:

echo /home/ilf/dir/file1.txt | awk -F/ '{print $NF}'

Here -F/ is a field separator while $NF is a built-in variable that gives the number of fields as output essentially referring to the last field. 

You can also provide a text file of paths to extract filenames from multiple paths. 

awk -F/ '{print $NF}' file_paths.txt

Here file_paths.txt is a file that contains the list of paths on each line. 

Get Filename using sed

sed is a powerful command line utility used to manipulate text on Linux and Unix-like operating systems. The command to extract the filename from a path is as follows:

echo /home/ilf/dir/file1.txt | sed 's:.*/::'

It can also extract filenames from a text file of paths.

sed 's:.*/::' file_paths.txt

Conclusion

The basename command in Linux is used to grab the filename from paths. It extracts filenames from multiple paths, either with or without file extensions. In this guide, we cover the syntax of basename command, how to use it in various ways. Moreover, we also explained alternative methods to get filenames from paths in bash.