How to Get Directory Path in Bash

Last updated: May 25, 2023 | Aditya Harsh

1. Introduction

When writing Bash scripts that deal with files and paths, it can become necessary to extract the directory path from the complete file path. Since Linux maintains a hierarchical structure to organize files and directories, this task becomes relatively easy. 

Parameter expansion in Bash offers a convenient method to extract relevant information from strings. Additionally, powerful built-in tools like sed, awk, and grep further enhance the extraction process. This tutorial explores different methods to extract the directory path in Bash and demonstrates their usage in practical examples.

2. Using dirname

Extracting directory is effortless thanks to the Bash built-in utility named dirname. It is very much similar to another Bash tool named basename, which works exactly in the same manner.

The only difference is that the dirname command prints whatever, the basename command discards. We can understand this from the following example:

Example:

dirname /home/ubuntu/sample/dirA/A_file.txt
basename /home/ubuntu/sample/dirA/A_file.txt
dirname: Returns directory path.
basename: Returns file name.

The dirname command works like the basename command. But it fetches the string the basename command trims. It is an equally simple tool to implement. All it does is finds the last path separator (/). It displays whatever is present before that.

The command is totally unbiased when it comes to files or directories. Its job is to simply give us the information prior to the final slash.

Example:

dirname /home/ubuntu/sample/dirB
The command dirname /home/ubuntu/sample/dirB will return: /home/ubuntu/sample

The command can interpret more than one input. It only requires a list of files, each separated by a space. In our example, we will get the directory structure of the two file paths, .bashrc and hosts from their respective paths. The output of the command will be two directory paths which will appear in separate lines. 

Example:

dirname /home/ubuntu/.bashrc /etc/hosts
/home/ubuntu/.bashrc returns: /home/ubuntu
/etc/hosts returns: /etc

3. Using parameter expansion

Parameter expansions are yet another interesting and useful tools at our disposal to extract the simply the path. It has a unique syntax. This kind of technique won't be available with other programming languages. Let us look at the below example to get an idea how it works.

Example:

filepath=/home/ubuntu/sample.txt

echo ${filepath%/*}

The above example can be generalized as follows:

${variable%pattern}
Parent directory of file path.

The first thing to notice is that parameter expansions cannot be applied to strings directly. There is no other option but to have that string present in a variable. Once the variable is initialized we are free to supply the expression which we want to trim. That pattern can be a regular expression as well. 

The task is to trim whatever we don't need. In this particular scenario, Bash trims the shortest match from the end of the pattern. It displays whatever is after the pattern. Even though this extraction is fast, the shortcoming is that we need a variable because of the parameter expansion. 

In our example, we have extracted the entire directory structure from the file path. We have used the parameter expansion technique. In the pattern we have used the regex (*) as the wildcard pattern. We have also added the path separator (/) before the regular expression. This slash represents the beginning of the file name with extension, if any. 

Bash will look for all the characters from the last occurrence of this slash and trim it. Hence, we will get the characters before the final path separator. This gives us the complete directory path.

4. Using powerful Bash tools

We talked about utilizing the powerful built-in tools to fetch the directory path for the given file path. Let us understand them one by one.

4.1 Using awk

Example:

path="/home/ubuntu/.bashrc"
echo "$path" | awk -F'/[^/]*$' '{print $1}'
using awk - return the directory path without filename.

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 (/). We then pick the first half using the {print $1}.

4.2 Using sed

Example:

path="/home/ubuntu/.bashrc"
echo "$path" | sed 's|/[^/]*$||'
using sed - return the directory path without filename.

In this example as well, we store  the entire file path in a variable. We can also feed the string directly to the echo command. We pipe the result of this echo command, which becomes the input to the sed command.

After that it is just a case of providing the right regular expression to the command. The s option with sed is used to tell Bash that sed wants to carry out substitution. We have taken the symbol | to act as a separator for the sed syntax. This character may be uniformly replaced by any other single character within any given s command.

The sed matcher selects the longest possible match. In our case, sed does not stop matching at "/home". Rather, it keeps matching until the string doesn’t have any more of the "/". That is why it displays the path /home/ubuntu. We can notice that the core regular expression /[^/]*$ in the above awk command and here has remained the same. 

5. Example Script

As we have learnt different ways of getting the directory path, we can look at an example that prompts the user to provide the complete path of the file. The script checks the directory path and displays all the files and directory present in that location.

Example:

#!/bin/bash 

read -p "Enter the filename with it's complete path: " path
path=`dirname $path`


if [ ! -d "$path" ]
then
	echo "Invalid file path. Please check the input."
else
	echo "The file path is correct. The files and folders in this directory are:"
	ls $path


fi
This is a Bash script that prompts the user to enter a filename with its complete path. It then extracts the directory component of the path using the dirname command.

1. The script begins by using the read command to prompt the user to enter the filename with its complete path. The entered value is stored in the variable named path.

2. The script then trims the filename with extension, if any and extracts the path of the directory using the dirname command. This is again stored in the same variable- path.

3. The script checks if the value present in the variable path is a directory or not using the -d test condition. If the directory structure doesn't exist, it prints "Invalid file path. Please check the input."

4. If the directory exists, the script displays all the files and folders present in there using the ls command.

6. Conclusion

  • We can fetch the directory path from the absolute file path.
  • Dirname is a simple enough command that can be used with certain limitations to pull out the complete directory path.
  • With parameter expansions, we can extract parts of a variable and hence the directory path.
  • We have seen the use of certain readily available powerful tools like awk and sed.
SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment