Whenever dealing with absolute paths, we will come across situations where we just need the name of the file. What do we do then? Definitely, we can use the available tools in Bash like awk.
We also have tailor-made tools whose sole purpose is to extract the final component in the file path. Basename is one such command-line utility. Another popular technique is the parameter expansion for removing the directory and trailing suffix from file names. In this tutorial, we will also examine the drawbacks of the different approaches and look at a real-world problem.
2. Why do we need to extract?
The obvious question is why to extract? We have multiple reasons to do so.
To rename the file or extension - We may want to extract the filename or extension to rename it with a new name or extension.
To have a new file name with the timestamp - We generally have log files in Linux with the same file name and extension. But the file name gets a suffix as the timestamp.
To perform certain actions on the directory like listing all the files in the directory where the given file is present.
To use it as an argument or as an input for the script or any Bash command.
3. Extract filename with extension
We will focus on three of the most common ways by which we can extract the filename with its extension in Bash.
3.1 Using basename
With Bash we can employ many utilities to extract the filename and the extension from the given file path. But, why go to such great lengths when we have a tailor-made tool whose sole purpose is to fetch the final component in the file path. Basename is a command-line tool for removing the directory and trailing suffix from file names.
Basename is a simple tool to implement. All it does is finds the last path separator (/). It displays whatever is present after that. As we can notice, the command is totally unbiased when it comes to files or directories. Its job is to simply give us the information after the final slash.
To make the command interpret more than one path, we supply -a. We can also give the --multiple flag. It is used to achieve the same. Then comes a list of files, each separated by a space.
Example:
basename -a /home/ubuntu/sample.txt /home/ubuntu/sample1.cfg
In our example, we will get the name of the two files with their respective extensions, sample.txt and sample1.cfg from their respective paths. These two will appear in separate lines.
To separate these outputs with NULL rather than a newline we have to pass the -z flag along with it.
One major drawback of this command is that it will extract the filename with the extension. We cannot use it just to extract the extension or the directory path.
3.2 Using parameter expansion
Bash has an interesting feature named parameter expansion. With parameter expansions, we can extract parts of a variable. It has a unique syntax. This won't be available with other programming languages.
This trims the longest match from the beginning till the pattern. It displays whatever is after the pattern. The only drawback is that we have to use a variable since this is a parameter expansion.
In our example, we have used the regex (*) as the pattern. In the pattern we have also added the path separator (/). It will look for all the characters till the last slash (/) and trim it. Hence, we will get the characters after the final path separator. The only drawback here is that we cannot use the string directory. There is no other option but to store the string in a variable.
3.3 Using awk
The awk command was developed by Aho, Weinberger, and Kernighan and gets its name from their initials. It is a powerful, widely used Linux tool that lets us process and manipulate data. It also supports performing arithmetic operations. We can also take its help to extract the filename with its extension.
In this example, we have taken a variable to hold the entire file path. We are free to supply that string directly to the echo command. We pipe the result of this echo command so that Bash can send it as an input to the awk command. The -F option available with the awk command acts as the field separator. We have built the regular expression for the awk statement in such a way that the string dissociates into two halves from the final slash (/). $NF ensures that Bash only prints the last column in the record.
4. Example Script
As we have learned different ways of fetching the name of the file, we can look at an example that prompts the user to provide the complete path of the file. The script checks the existence of the file. It then asks the user to provide the directory where he wants to keep a backup of this file with the same name and extension.
Example:
#!/bin/bash
read -p "Enter the filename with it's complete path: " fpath
if [ ! -f "$fpath" ]
then
echo "Invalid file. Please check the input."
else
read -p "Enter the complete path where you want to copy it: " fdir
if [ ! -d "$fdir" ]
then
echo "Invalid new directory. Please check the input."
else
fname=`basename $fpath`
cp $fpath ${fdir}/${fname}
fi
fi
1. The script begins by prompting the user to enter the filename with its complete path. It does it by employing the read command. The user input is stored in the fpath variable.
2. The script verifies the existence of the file specified in fpath using the -f test condition. If the file doesn't exist, it prints "Invalid file. Please check the input."
3. If the file exists, the script again prompts the user to enter the complete path of the destination directory where the file should be copied to. The entered value is stored in the fdir variable.
4. It then checks if the directory specified by fdir does not exist using the -d test condition. If the directory doesn't exist, it prints "Invalid new directory. Please check the input."
5. If both the file and the directory exist, the script uses the basename command to extract the filename from the given file path and stores it in the fname variable.
6. Finally, the cp command is used to copy the file specified by fpath to the destination directory ${fdir}/${fname}.
5. Conclusion
We can fetch the file name along with its extension from the absolute file path.
Basename is a simple enough command that can be used with certain limitations to pull out the filename.
With parameter expansions, we can extract parts of a variable and name of the file
We have seen the use of certain readily available powerful tools like awk.
If this resource helped you, let us know your care by a Thanks Tweet.
Did you find this article helpful?
We are glad you liked the article. Share with your friends.
About The Author
Aditya Harsh
Aditya graduated from BITS Pilani, India with a Bachelor's in Computer Science in 2015. Since then he has been working as a software developer and specializes in automation such as Linux bash. Over these years, he has worked on a lot of cutting-edge technologies and enjoys using his skills to contribute to technological advances. He believes in the power of knowledge and take great joy in sharing what he has learned.
Comments