98

Is there a way to get absolute path of a file that is being searched?

For example:

find .. -name "filename"

It gives me results like ../filename but I want the full path.

What I need is to find in the parent directory and its children, for a specific file, that I will use in another script later.

Thanks

Radu Rădeanu
  • 169,590
JorgeeFG
  • 1,996
  • 1
  • find $(readlink -f ..) -name "filename". Use readlink in the file path for ease. – Veno Mar 03 '23 at 06:50
  • the comment here using readlink is the best answer by far, but I'll just add that (1) quotes are important in case there's a space in the dir name, and (2) realpath is apparently preferred according to man readlink(1): eg: find "$(realpath ..)" -name "filename" (nb: find ... -printf ... has no option for this, and find ... - exec readlink -f {} \; is suuuuper slow) – michael Jan 20 '24 at 02:50

10 Answers10

94

You can use bash's Tilde Expansion to get the absolute path of the current working directory, this way find prints the absolute path for the results as well:

find ~+ -type f -name "filename"

If executed in ~/Desktop, this is expanded to

find /home/yourusername/Desktop -type f -name "filename"

and prints results like:

/home/yourusername/Desktop/filename

If you want to use this approach with the current working directory’s parent directory you need to cd before calling find:

cd .. && find ~+ -type f -name "filename"
GcL
  • 103
dessert
  • 39,982
39

Try something like:

find "$(cd ..; pwd)" -name "filename"
  • Thanks, I was just testing $(cd ..; pwd). Here it works OK, but if I do it alone in a Terminal, I can't get the parent dir... I get "Bash: : Is a directory. And if I do $(cd ..; echo "something") I get "something: not a command" – JorgeeFG Apr 07 '14 at 15:52
  • 1
    Do you mean like a separate command? Then you would need to leave out the dollar sign: (cd ..; pwd) – Scrutinizer Apr 07 '14 at 15:53
  • Thanks, that was it. Any reference of why should I remove the $, how does it affect the subshell? – JorgeeFG Apr 07 '14 at 15:56
  • 1
    Yes ( ... ) means execute in a subshell, the output gets written to stdout. $( ... ) stands for "command substitution". The latter can be used as if it were a variable expansion. – Scrutinizer Apr 07 '14 at 16:03
  • find / -name "filename" – Panther Apr 07 '14 at 18:48
  • @bodhi.zazen : That would list every occurrence from the root down, which is not the requirement and which may give wrong results if there are multiples files present with that name, it is also unnecessarily taxing on the system. – Scrutinizer Apr 08 '14 at 11:32
  • 2
    @Scrutinizer - I think you misunderstand how find works. If you use the full path in your search, you get the full path in your output. find /home/your_user -name foo. As OP is using "../" , hard to guess the full path to give in an answer. – Panther Apr 08 '14 at 13:02
  • @bodhi.zazen If you use / then find starts looking from the root instead of from the directory that the OP specified. Do you understand what pwd does in the suggestion I gave? What is the first character that pwd returns? – Scrutinizer Apr 08 '14 at 14:10
  • 2
    @JorgeeFG $(builtin cd ..; pwd) will canel functions, aliases. –  Oct 16 '19 at 17:37
27

The simplest way is

find "$(pwd -P)" -name "filename"
Vivek
  • 379
26

Try using the -exec option of find:

find .. -name "filename" -exec readlink -f {} \;

Note: readlink prints the value of a symbolic link or canonical file name.

  • 2
    this will call readlink on every file so it will be very ineffective. –  Oct 16 '19 at 18:20
  • I like the simplicity of this solution but I found xargs to be much faster.............................................. find .. -name "filename" | xargs readlink -f – brotherJ4mes Nov 13 '20 at 16:39
11

This worked for me, but will only return the first occurrence.

realpath $(find . -type f -name filename -print -quit)

To get full paths for all occurrences (as suggested by Sergiy Kolodyazhnyy)

find . -type f -name filename -print0 | xargs -0 realpath
DawnSong
  • 103
Wyrmwood
  • 206
  • 2
  • 5
6

Try this way:

find $PWD -name "filename"
3

Unless I totally misunderstand, it is as simple as this:

find $(realpath .) -name 'river.jpg'

By specifying the full real path as a start, find will implicitly output this full path as a search result.

The bash command realpath converts the current (or any other directory as ./images) into its real path). the $(realpath .) converts the output to a variable, as if it was typed manually, e.g. /home/myusername

anonymous2
  • 4,298
Pelton
  • 31
2

Try with -printf. This also works with files with blank spaces.

find .. -name "filename" -printf $PWD/"%f\n"

1

Removing last directory component with parameter Expansion.

find "${PWD%/*}" -name 'filename'

An example of how you can use mapfile to save output from find to an indexed array for later use.

mapfile -t -d '' < <(find ${PWD%/*} -name 'filename' -print0)

(if no array name is specified, MAPFILE will be the default array name).

for i in "${MAPFILE[@]}"; do
    echo "$((n++)) $i"
done
1

Also using PWD can show you the full directory. Pwd will show you all your directorys you are in like the expanding of filename. Hope this helped.