Question

I am writing a shell script that takes file paths as input.

For this reason, I need to generate recursive file listings with full paths. For example, the file bar has the path:

/home/ken/foo/bar

but, as far as I can see, both ls and find only give relative path listings:

./foo/bar   (from the folder ken)

It seems like an obvious requirement, but I can't see anything in the find or ls man pages.

How can I generate a list of files in the shell including their absolute paths?

Was it helpful?

Solution

If you give find an absolute path to start with, it will print absolute paths. For instance, to find all .htaccess files in the current directory:

find "$(pwd)" -name .htaccess

or if your shell expands $PWD to the current directory:

find "$PWD" -name .htaccess

find simply prepends the path it was given to a relative path to the file from that path.

Greg Hewgill also suggested using pwd -P if you want to resolve symlinks in your current directory.

OTHER TIPS

readlink -f filename 

gives the full absolute path. but if the file is a symlink, u'll get the final resolved name.

Use this for dirs (the / after ** is needed in bash to limit it to directories):

ls -d -1 "$PWD/"**/

this for files and directories directly under the current directory, whose names contain a .:

ls -d -1 "$PWD/"*.*

this for everything:

ls -d -1 "$PWD/"**/*

Taken from here http://www.zsh.org/mla/users/2002/msg00033.html

In bash, ** is recursive if you enable shopt -s globstar.

You can use

find $PWD 

in bash

ls -d "$PWD/"*

This looks only in the current directory. It quotes "$PWD" in case it contains spaces.

The $PWD is a good option by Matthew above. If you want find to only print files then you can also add the -type f option to search only normal files. Other options are "d" for directories only etc. So in your case it would be (if i want to search only for files with .c ext):

find $PWD -type f -name "*.c" 

or if you want all files:

find $PWD -type f

Note: You can't make an alias for the above command, because $PWD gets auto-completed to your home directory when the alias is being set by bash.

If you give the find command an absolute path, it will spit the results out with an absolute path. So, from the Ken directory if you were to type:

find /home/ken/foo/ -name bar -print    

(instead of the relative path find . -name bar -print)

You should get:

/home/ken/foo/bar

Therefore, if you want an ls -l and have it return the absolute path, you can just tell the find command to execute an ls -l on whatever it finds.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

NOTE: There is a space between {} and ;

You'll get something like this:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

If you aren't sure where the file is, you can always change the search location. As long as the search path starts with "/", you will get an absolute path in return. If you are searching a location (like /) where you are going to get a lot of permission denied errors, then I would recommend redirecting standard error so you can actually see the find results:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

(2> is the syntax for the Borne and Bash shells, but will not work with the C shell. It may work in other shells too, but I only know for sure that it works in Bourne and Bash).

Command: ls -1 -d "$PWD/"*

This will give the absolute paths of the file like below.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }

Here's an example that prints out a list without an extra period and that also demonstrates how to search for a file match. Hope this helps:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

find / -print will do this

ls -1 | awk  -vpath=$PWD/ '{print path$1}'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top