Extracting the directory path from a file path is a common task in shell scripting, particularly when working with files and directories. In this tutorial, we will explore how to achieve this using various methods in Bash.
Using dirname
Command
The dirname
command is specifically designed for extracting the directory path from a given file path. It is part of the POSIX standard, making it widely available on most platforms that support Bash. Here’s an example of how to use dirname
:
VAR='/home/pax/file.c'
DIR=$(dirname "${VAR}")
echo "${DIR}"
When you run this code, it will output: /home/pax
. This demonstrates how dirname
can be used to extract the directory path from a file path.
Using Parameter Expansion
Bash also provides parameter expansion, which allows you to manipulate strings without needing external commands. You can use the ${parameter%word}
syntax to remove the smallest suffix (in this case, the filename) from the parameter. Here’s how to do it:
VAR='/home/me/mydir/file.c'
DIR=${VAR%/*}
echo "${DIR}"
This will output: /home/me/mydir
, which is the directory path extracted from the file path.
Handling Relative Paths and Symbolic Links
When dealing with relative paths or symbolic links, using dirname
alone may not yield the desired result. For instance, if you only have a filename without its full path, dirname
will simply output .
(the current directory). To handle such cases, you can combine readlink
with dirname
. The readlink -f
command resolves symbolic links and returns the absolute path of the file.
fname='txtfile'
echo $(dirname "$fname") # Output: .
echo $(readlink -f "$fname") # Output: /home/me/work/txtfile
Then, to get just the directory:
echo $(dirname $(readlink -f "$fname")) # Output: /home/me/work
Checking for Symbolic Links
If you’re working with files that could be symbolic links, it’s a good idea to check for this and handle them accordingly. You can use the [ -h $file ]
test to see if a file is a symbolic link.
if [ -h "$file" ]; then
base=$(dirname $(readlink "$file"))
else
base=$(dirname "$file")
fi
Getting the Directory of the Current Script
Sometimes, you might need to get the directory path of the current script. This can be achieved using $(dirname $BASH_SOURCE)
in combination with cd
and pwd
to ensure you get an absolute path.
HERE=$(cd $(dirname "$BASH_SOURCE") && pwd)
This sets the HERE
variable to the full path of the directory containing the current script, which can be useful for scripting purposes.
Conclusion
Extracting directory paths from file paths in Bash is straightforward and can be accomplished using various methods, including the dirname
command, parameter expansion, and combinations of readlink
and dirname
. Understanding these techniques will help you write more effective shell scripts that handle files and directories with ease.