How to retrieve absolute path given relative

Is there a command to retrieve the absolute path given the relative path?

For example I want $line to contain the absolute path of each file in dir ./etc/

find ./ -type f | while read line; do
   echo $line
done

Solution 1:

Try realpath.

~ $ sudo apt-get install realpath  # may already be installed
~ $ realpath .bashrc
/home/username/.bashrc

To avoid expanding symlinks, use realpath -s.

The answer comes from "bash/fish command to print absolute path to a file".

Solution 2:

If you have the coreutils package installed you can generally use readlink -f relative_file_name in order to retrieve the absolute one (with all symlinks resolved)

Solution 3:

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

UPD Some explanations

  1. This script get relative path as argument "$1"
  2. Then we get dirname part of that path (you can pass either dir or file to this script): dirname "$1"
  3. Then we cd "$(dirname "$1") into this relative dir and get absolute path for it by running pwd shell command
  4. After that we append basename to absolute path: $(basename "$1")
  5. As final step we echo it

Solution 4:

use:

find "$(pwd)"/ -type f

to get all files or

echo "$(pwd)/$line"

to display full path (if relative path matters to)

Solution 5:

For what it's worth, I voted for the answer that was picked, but wanted to share a solution. The downside is, it's Linux only - I spent about 5 minutes trying to find the OSX equivalent before coming to Stack overflow. I'm sure it's out there though.

On Linux you can use readlink -e in tandem with dirname.

$(dirname $(readlink -e ../../../../etc/passwd))

yields

/etc/

And then you use dirname's sister, basename to just get the filename

$(basename ../../../../../passwd)

yields

passwd

Put it all together..

F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"

yields

/etc/passwd

You're safe if you're targeting a directory, basename will return nothing and you'll just end up with double slashes in the final output.