Is there an easy way I can print the full path of file.txt ?
file.txt = /nfs/an/disks/jj/home/dir/file.txt The <command>
dir> <command> file.txt should print
/nfs/an/disks/jj/home/dir/file.txt Use readlink:
readlink -f file.txt The readlink man page (dated Jan 2025) now contains this note:
realpath(1) is a better command for canonicalization functionality.
Accordingly, use realpath:
realpath file.txt brew install coreutils then greadlink -f file.txtreadlink: Note realpath is the preferred command to use for canonicalization functionality.I suppose you are using Linux.
I found a utility called realpath in coreutils 8.15.
realpath -s file.txt /data/ail_data/transformed_binaries/coreutils/test_folder_realpath/file.txt Since the question is about how to get the full/absolute path of a file and not about how to get the target of symlinks, use -s or --no-symlinks which means don't expand symlinks.
As per @styrofoam-fly and @arch-standton comments, realpath alone doesn't check for file existence, to solve this add the e argument: realpath -e file
realpath was committed to the coreutils repo end of 2011, release 8.15 was done in January 2012, I answered the question (with the readlink suggestion) in March 2011 :)realpath -e prints an error if the argument doesn't exist.-s option to not expand symlinks.The following usually does the trick:
echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")" LOCAL_VARIABLE="filename.txt" && echo $(cd $(dirname "$LOCAL_VARIABLE") && pwd -P)/$(basename "$LOCAL_VARIABLE")readlink doesn't work if the file is a symlink, it will show you the target of the symlink instead of the symlink itself.readlink takes me back to the parent dir where the symbolic link generates from, but this ignores it.Shift and right clicking on a file in Windows Explorer gives you an option called Copy as Path. This will copy the full path of the file to clipboard. realpath yourfile to get the full path of a file as suggested by others.find $PWD -type f | grep "filename" or
find $PWD -type f -name "*filename*" find `pwd` -type file -name \*.dmpfind $PWD that works perfectly for me when it's just a few filesIf you are in the same directory as the file:
ls "`pwd`/file.txt" Replace file.txt with your target filename.
echo $(pwd)/file.txtI know that this is an old question now, but just to add to the information here:
The Linux command which can be used to find the filepath of a command file, i.e.
$ which ls /bin/ls There are some caveats to this; please see https://www.cyberciti.biz/faq/how-do-i-find-the-path-to-a-command-file/.
You could use the fpn (full path name) script:
% pwd /Users/adamatan/bins/scripts/fpn % ls LICENSE README.md fpn.py % fpn * /Users/adamatan/bins/scripts/fpn/LICENSE /Users/adamatan/bins/scripts/fpn/README.md /Users/adamatan/bins/scripts/fpn/fpn.py fpn is not a standard Linux package, but it's a free and open github project and you could set it up in a minute.
pwd by itself should run fine on Linux and most other Unix-like OS environments.Works on Mac, Linux, *nix:
This will give you a quoted csv of all files in the current dir:
ls | xargs -I {} echo "$(pwd -P)/{}" | xargs | sed 's/ /","/g' The output of this can be easily copied into a python list or any similar data structure.
This solution uses commands that exist on Ubuntu 22.04, but generally exist on most other Linux distributions, unless they are just too hardcore for s'mores.
The shortest way to get the full path of a file on Linux or Mac is to use the ls command and the PWD environment variable.
<0.o> touch afile <0.o> pwd /adir <0.o> ls $PWD/afile /adir/afile You can do the same thing with a directory variable of your own, say d.
<0.o> touch afile <0.o> d=/adir <0.o> ls $d/afile /adir/afile Notice that without flags ls <FILE> and echo <FILE> are equivalent (for valid names of files in the current directory), so if you're using echo for that, you can use ls instead if you want.
If the situation is reversed, so that you have the full path and want the filename, just use the basename command.
<0.o> touch afile <0.o> basename $PWD/afile afile echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1") This is explanation of what is going on at @ZeRemz's answer:
"$1"dirname "$1"cd "$(dirname "$1") into this relative dir && pwd -P and get absolute path for it. -P option will avoid all symlinks$(basename "$1")echo itYou may use this function. If the file name is given without relative path, then it is assumed to be present in the current working directory:
abspath() { old=`pwd`;new=$(dirname "$1");if [ "$new" != "." ]; then cd $new; fi;file=`pwd`/$(basename "$1");cd $old;echo $file; } Usage:
$ abspath file.txt /I/am/in/present/dir/file.txt Usage with relative path:
$ abspath ../../some/dir/some-file.txt /I/am/in/some/dir/some-file.txt With spaces in file name:
$ abspath "../../some/dir/another file.txt" /I/am/in/some/dir/another file.txt I was surprised no one mentioned located.
If you have the locate package installed, you don't even need to be in the directory with the file of interest.
Say I am looking for the full pathname of a setenv.sh script. This is how to find it.
$ locate setenv.sh /home/davis/progs/devpost_aws_disaster_response/python/setenv.sh /home/davis/progs/devpost_aws_disaster_response/webapp/setenv.sh /home/davis/progs/eb_testy/setenv.sh Note, it finds three scripts in this case, but if I wanted just one I would do this:
$ locate *testy*setenv.sh /home/davis/progs/eb_testy/setenv.sh In a similar scenario, I'm launching a cshell script from some other location. For setting the correct absolute path of the script so that it runs in the designated directory only, I'm using the following code:
set script_dir = `pwd`/`dirname $0` $0 stores the exact string how the script was executed.
For e.g. if the script was launched like this: $> ../../test/test.csh, $script_dir will contain /home/abc/sandbox/v1/../../test
./test.csh you will have a path ending with /test/.For Mac OS X, I replaced the utilities that come with the operating system and replaced them with a newer version of coreutils. This allows you to access tools like readlink -f (for absolute path to files) and realpath (absolute path to directories) on your Mac.
The Homebrew version appends a 'G' (for GNU Tools) in front of the command name -- so the equivalents become greadlink -f FILE and grealpath DIRECTORY.
Instructions for how to install the coreutils/GNU Tools on Mac OS X through Homebrew can be found in this StackExchange arcticle.
NB: The readlink -f and realpath commands should work out of the box for non-Mac Unix users.
brew install coreutilsYou can save this in your shell.rc or just put in console
function absolute_path { echo "$PWD/$1"; } alias ap="absolute_path" example:
ap somefile.txt will output
/home/user/somefile.txt ap ../foobar.txt will give /home/user/../foobar.txt, which is not generally what you want.ap /tmp/foobar.txt will give /home/user//tmp/foobar.txt, which is wrong.I like many of the answers already given, but I have found this really useful, especially within a script to get the full path of a file, including following symlinks and relative references such as . and ..
dirname `readlink -e relative/path/to/file` Which will return the full path of the file from the root path onwards. This can be used in a script so that the script knows which path it is running from, which is useful in a repository clone which could be located anywhere on a machine.
basePath=`dirname \`readlink -e $0\`` I can then use the ${basePath} variable in my scripts to directly reference other scripts.
Hope this helps,
Dave
This worked pretty well for me. It doesn't rely on the file system (a pro/con depending on need) so it'll be fast; and, it should be portable to most any *NIX. It does assume the passed string is indeed relative to the PWD and not some other directory.
function abspath () { echo $1 | awk '\ # Root parent directory refs to the PWD for replacement below /^\.\.\// { sub("^", "./") } \ # Replace the symbolic PWD refs with the absolute PWD \ /^\.\// { sub("^\.", ENVIRON["PWD"])} \ # Print absolute paths \ /^\// {print} \' } This is naive, but I had to make it to be POSIX compliant. Requires permission to cd into the file's directory.
#!/bin/sh if [ ${#} = 0 ]; then echo "Error: 0 args. need 1" >&2 exit 1 fi if [ -d ${1} ]; then # Directory base=$( cd ${1}; echo ${PWD##*/} ) dir=$( cd ${1}; echo ${PWD%${base}} ) if [ ${dir} = / ]; then parentPath=${dir} else parentPath=${dir%/} fi if [ -z ${base} ] || [ -z ${parentPath} ]; then if [ -n ${1} ]; then fullPath=$( cd ${1}; echo ${PWD} ) else echo "Error: unsupported scenario 1" >&2 exit 1 fi fi elif [ ${1%/*} = ${1} ]; then if [ -f ./${1} ]; then # File in current directory base=$( echo ${1##*/} ) parentPath=$( echo ${PWD} ) else echo "Error: unsupported scenario 2" >&2 exit 1 fi elif [ -f ${1} ] && [ -d ${1%/*} ]; then # File in directory base=$( echo ${1##*/} ) parentPath=$( cd ${1%/*}; echo ${PWD} ) else echo "Error: not file or directory" >&2 exit 1 fi if [ ${parentPath} = / ]; then fullPath=${fullPath:-${parentPath}${base}} fi fullPath=${fullPath:-${parentPath}/${base}} if [ ! -e ${fullPath} ]; then echo "Error: does not exist" >&2 exit 1 fi echo ${fullPath} find / -samefile file.txt -print Will find all the links to the file with the same inode number as file.txt
adding a -xdev flag will avoid find to cross device boundaries ("mount points"). (But this will probably cause nothing to be found if the find does not start at a directory on the same device as file.txt)
Do note that find can report multiple paths for a single filesystem object, because an Inode can be linked by more than one directory entry, possibly even using different names. For instance:
find /bin -samefile /bin/gunzip -ls Will output:
12845178 4 -rwxr-xr-x 2 root root 2251 feb 9 2012 /bin/uncompress 12845178 4 -rwxr-xr-x 2 root root 2251 feb 9 2012 /bin/gunzip Beside "readlink -f" , another commonly used command:
$find /the/long/path/but/I/can/use/TAB/to/auto/it/to/ -name myfile /the/long/path/but/I/can/use/TAB/to/auto/it/to/myfile $
This also give the full path and file name at console
Off-topic: This method just gives relative links, not absolute. The readlink -f command is the right one.