Absolute, Relative, and Splitting Paths in Bash

The main stumbling block with splitting paths in Bash is converting a relative path into an absolute one.

Searching the Internet I found many partial solutions, but none was entirely satisfactory. There may be a better solution out there, but I didn’t find it.

For example

ABSPATH="`realpath "${RELPATH}"`"

does work, but

  • <realpath> may not be included in a standard distribution
  • this only works for existing files

Alternatively, there’s

DIRABSPATH="`cd ${DIRRELPATH}; pwd`"

or

FILEABSPATH="`cd \`dirname "${FILERELPATH}"\`; pwd`/`basename "${FILERELPATH}"`"

but again

  • these only work for existing directories or files in existing directories respectively

Therefore, I propose another, but still imperfect, solution. First, in your script, define a function:

function abspath
{
  RELPATH="${1}"
  PYTHONPROG="import os; print os.path.abspath(\"${RELPATH}\")"
  ABSPATH="`python -c \"${PYTHONPROG}\"`"
  echo ${ABSPATH}
}

This may then be called thus:

ABSPATH="`abspath ${RELPATH}`"

The problem with this is:

  • it requires Python

On the other hand

  • it works whether or not the path already exists

To further split the parts of a path, here are some further commands for a Bash script:

FILERELPATH="${1}"
FILEPATH="`abspath ${FILERELPATH}`"
FILEDIR="`dirname "${FILEPATH}"`/"
FILENAME="`basename "${FILEPATH}"`"
FILEBASE="${FILENAME%.*}"
FILEEXT="${FILENAME:${#FILEBASE}}"

Thus the input

~/myproject/splitpath.sh.tmpl

might result in

FILEPATH = /home/Rob/myproject/splitpath.sh.tmpl
FILEDIR = /home/Rob/myproject/
FILENAME = splitpath.sh.tmpl
FILEBASE = splitpath.sh
FILEEXT = .tmpl

Note that:

${FILEPATH} == ${FILEDIR}${FILENAME}
            == ${FILEDIR}${FILEBASE}${FILEEXT}

and

  • an empty extension is handled correctly
  • if the file path is a directory, this doesn’t quite work, even if a trailing slash (/) is provided

An alternative line for the file base above is

FILEBASE="${FILENAME%%.*}"

The former results in making the base as long and the extension as short as possible, whereas the latter works conversely.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: