304

I would like to determine the location of a file using command-line. I have tried:

find . -type f -name "postgis-2.0.0"

and

locate postgis-2.0.0

to no avail. What is the command to determine the file's directory, provided its name?

2
  • 3
    the locate command is fine, just update the locatedb first, using command updatedb
    – thucnguyen
    May 18, 2016 at 3:53
  • If it is already installed, new filename might not be postgis-2.0.0 anymore. Usually after installations via package managers, executables would be in one of the $PATH folders, try which postgis to see the location. If it returns nothing, only then you should manually look for file location.
    – user311189
    Jul 29, 2016 at 15:44

9 Answers 9

378

Try find ~/ -type f -name "postgis-2.0.0" instead.

Using . will only search the current directory. ~/ will search your entire home directory (likely where you downloaded it to). If you used wget as root, its possible it could be somewhere else so you could use / to search the whole filesystem.

Goodluck

4
  • 1
    oh ya i used wget as root so / worked thanks
    – Sam007
    May 31, 2012 at 17:09
  • for more check this link help.ubuntu.com/community/find
    – habibun
    Dec 4, 2016 at 5:03
  • I get find: /Users/UserName//Library/Saved Application State/com.bitrock.appinstaller.savedState: Permission denied error. it appears on every execution of the command. How to get rid of it?
    – Eduard
    Jun 14, 2018 at 14:08
  • you need permissions, sudo find ... should work
    – Alfonso
    Aug 4, 2022 at 10:02
42

I would try:

sudo find / -type d -name "postgis-2.0.0"

The . means search only in the current directory, it is best to search everything from root if you really don't know. Also, type -f means search for files, not folders. Adding sudo allows it to search in all folders/subfolders.

Your syntax for locate is correct, but you may have to run

sudo updatedb

first. For whatever reason, I never have good luck with locate though.

locate uses database of files and directories made by updatedb. So if you have downloaded a new file there is more chance that your updatedb has not updated the database of files and directories. You can use sudo updatedb before using locate utility program. updatedb generally runs once a day by itself on linux systems.

1
  • 1
    sudo updatedb before searching helped me.
    – avn
    Jan 20, 2021 at 12:49
26

The other answers are good, but I find omitting Permission denied statements gives me clearer answers (omits stderrs due to not running sudo):

find / -type f -iname "*postgis-2.0.0*" 2>/dev/null

where:

  • / can be replaced with the directory you want to start your search from
  • f can be replaced with d if you're searching for a directory instead of a file
  • -iname can be replaced with -name if you want the search to be case sensitive
  • the *s in the search term can be omitted if you don't want the wildcards in the search

An alternative is:

find / -type f 2>/dev/null | grep "postgis-2.0.0"

This way returns results if the search-term matches anywhere in the complete file path, e.g. /home/postgis-2.0.0/docs/Readme.txt

3
  • 2
    There are -regex and -iregex switches for searching with Regular Expressions, which would find the path mentions as well. Suggestion to find any item which is a file (-type f) then grep is more resource expensive. Permission denied happens when user doesn't have access to files or folders, using sudo before find will allow find to see all files.
    – user311189
    Jul 29, 2016 at 15:51
  • 1
    Good to know about the regex switches, thanks.
    – zanbri
    Jul 29, 2016 at 15:55
  • @zanbri Use -wholename or -iwholename instead of piping to grep.
    – wjandrea
    Dec 4, 2016 at 8:13
15

find is one of the most useful Linux/Unix tools.

Try find . -type d | grep DIRNAME

3
  • 1
    Is there any advantage here to using grep over -name ?
    – TryHarder
    Feb 1, 2016 at 23:40
  • @oooooo I added a reason in my answer below
    – zanbri
    Jul 29, 2016 at 15:38
  • find plus grep was the only thing that worked for me
    – malhal
    Feb 2, 2017 at 23:25
14

Try find . -name "*file_name*"

  • where you can change '.'(look into the Current Directory) to '/'(look into the entire system) or '~/'(look into the Home Directory).

  • where you can change "-name" to "-iname" if you want no case sensitive.

  • where you can change "file_name"(a file that can start and end with whatever it is) to the exactly name of the file.

5

This should simplify the locating of file:

This would give you the full path to the file

tree -f  / | grep postgis-2.0.0

Tree lists the contents of directories in a tree-like format. the -f tells tree to give the full path to the file. since we have no idea of its location or parent location, good to search from the filesystem root / recursively downwards. We then send the output to grep to highlight our word, postgis-2.0.0

2

$ find . -type f | grep IMG_20171225_*
Gives
./03-05--2018/IMG_20171225_200513.jpg
The DOT after the command find is to state a starting point,
Hence - the current folder,
"piped" (=filtered) through the name filter IMG_20171225_*

0

While find command is simplest way to recursively traverse the directory tree, there are other ways and in particular the two scripting languages that come with Ubuntu by default already have the ability to do so.

bash

bash has a very nice globstar shell option, which allows for recursive traversal of the directory tree. All we need to do is test for whether item in the ./**/* expansion is a file and whether it contains the desired text:

bash-4.3$ for f in ./**/* ;do [ -f "$f" ] && [[ "$f" =~ "postgis-2.0.0" ]] && echo "$f"; done 
./testdir/texts/postgis-2.0.0

Perl

Perl has Find module, which allows to perform recursive traversal of directory tree, and via subroutine perform specific action on them. With a small script, you can traverse directory tree, push files that contain the desired string into array, and then print it like so:

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;

my @wanted_files;
find(
     sub{ 
         -f $_ && $_ =~ $ARGV[0]  
               && push @wanted_files,$File::Find::name
     }, "."
);

foreach(@wanted_files){
    print "$_\n"
}

And how it works:

$ ./find_file.pl  "postgis-2.0.0"                                                       
./testdir/texts/postgis-2.0.0

Python

Python is another scripting language that is used very widely in Ubuntu world. In particular, it has os.walk() module which allows us to perform the same action as above - traverse directory tree and obtain list of files that contain desired string.

As one-liner this can be done as so:

$ python -c 'import os;print([os.path.join(r,i) for r,s,f in os.walk(".") for i in f if "postgis-2.0.0" in i])'                                                                         
['./testdir/texts/postgis-2.0.0']

Full script would look like so:

#!/usr/bin/env python
import os;

for r,s,f in os.walk("."):
    for i in f:
        if "postgis-2.0.0" in i:
            print(os.path.join(r,i))
0

Try find -iname filename.txt command.

This command searches for and displays the paths of all files that exist in the system.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .