Get file directory path from file path
Get file directory path from file path
Question
In Bash, if VAR="/home/me/mydir/file.c"
, how do I get "/home/me/mydir"
?
Accepted Answer
dirname
and basename
are the tools you're looking for for extracting path components:
$ export VAR='/home/pax/file.c'
$ echo "$(dirname "${VAR}")" ; echo "$(basename "${VAR}")"
/home/pax
file.c
They're not internal Bash commands but they're part of the POSIX standard - see dirname
and basename
. Hence, they're probably available on, or can be obtained for, most platforms that are capable of running bash
.
Read more... Read less...
$ export VAR=/home/me/mydir/file.c
$ export DIR=${VAR%/*}
$ echo "${DIR}"
/home/me/mydir
$ echo "${VAR##*/}"
file.c
To avoid dependency with basename
and dirname
On a related note, if you only have the filename or relative path, dirname
on its own won't help. For me, the answer ended up being readlink
.
fname='txtfile'
echo $(dirname "$fname") # output: .
echo $(readlink -f "$fname") # output: /home/me/work/txtfile
You can then combine the two to get just the directory.
echo $(dirname $(readlink -f "$fname")) # output: /home/me/work
If you care target files to be symbolic link, firstly you can check it and get the original file. The if clause below may help you.
if [ -h $file ]
then
base=$(dirname $(readlink $file))
else
base=$(dirname $file)
fi
I was playing with this and came up with an alternative.
$ VAR=/home/me/mydir/file.c
$ DIR=`echo $VAR |xargs dirname`
$ echo $DIR
/home/me/mydir
The part I liked is it was easy to extend backup the tree:
$ DIR=`echo $VAR |xargs dirname |xargs dirname |xargs dirname`
$ echo $DIR
/home
Here is a script I used for recursive trimming. Replace $1 with the directory you want, of course.
BASEDIR="$1"
IFS=$'\n'
cd $BASEDIR
for f in $(find . -type f -name ' *')
do
DIR=$(dirname "$f")
DIR=${DIR:1}
cd $BASEDIR$DIR
rename 's/^ *//' *
done