Search Commands

Linux find command

The Linux find command is a very useful to search for files from the command line. It can be used to find files based on variety of filters and parameters like type, name, modification date/time, size etc..

To find a file by name

$ find -name install.log
./install.log

To find a file by name, but ignore the case of the query

$ find -iname install.log
./Install.log
./install.log

You can invert the search with “-not” or “!”. If you use “!”, you must escape the character so that bash does not try to interupt it before find can act.

$ find -not -name install.log
.
./Install.log
./anaconda-ks.cfg
./.xauthntfvB2
./.cshrc
./.bash_profile
./.xauthmlFVbC

OR

$ find \! -name install.log
.
./Install.log
./anaconda-ks.cfg
./.xauthntfvB2
./.cshrc
./.bash_profile
./.xauthmlFVbC

List all files in current and sub directories

$ find
.
./Install.log
./anaconda-ks.cfg
./.xauthntfvB2
./.cshrc
./.bash_profile
./.xauthmlFVbC
./install.log
./install.log.syslog
./.bash_history

The command is same as the following

$ find .
$ find . -print

Search specific directory or path

$ find /home/myftp/
/home/myftp/
/home/myftp/.bash_profile
/home/myftp/.mozilla
/home/myftp/.mozilla/extensions
/home/myftp/.mozilla/plugins
/home/myftp/.bash_logout
/home/myftp/ftp.txt
/home/myftp/.bashrc
/home/myftp/.gnome2

Finding by Type

You can specify the type of files you want to find with the “-type” parameter.

find -type type_descriptor query

Some of the most common descriptors that you can use to specify the type of file are here

  • f: regular file

  • d: directory

  • l: symbolic link

  • c: character devices

  • b: block devices

If we wanted to find all the directories under /home/myftp, issue below command.

$ find /home/myftp -type d
/home/myftp
/home/myftp/.mozilla
/home/myftp/.mozilla/extensions
/home/myftp/.mozilla/plugins
/home/myftp/.gnome2

We can also use wildcards, search for all files that end in “.log”

$ find / -type f -name "*.log"

Hidden files on linux begin with a period. So its easy to mention that in the name criteria and list all hidden files.

$ find ~ -type f -name ".*"

Limit depth of directory traversal

The find command by default travels down the entire directory tree recursively, which is time and resource consuming. However the depth of directory travesal can be specified. For example we don’t want to go more than 2 or 3 levels down in the sub directories. This is done using the maxdepth option.

$ find ./test -maxdepth 2 -name "*.php"
./test/subdir/how.php
./test/cool.php
find ./test -maxdepth 1 -name *.php
./test/cool.php

The second example uses maxdepth of 1, which means it will not go lower than 1 level deep, either only in the current directory.

This is very useful when we want to do a limited search only in the current directory or max 1 level deep sub directories and not the entire directory tree which would take more time.

Just like maxdepth there is an option called mindepth which does what the name suggests, that is, it will go at least N level deep before searching for the files.

$ find -mindepth 4 -name file

You can combine the min and max depth parameters to focus in on a narrow range:

$ find -mindepth 2 -maxdepth 3 -name file

Combine multiple search criteria

It is possible to use multiple criterias when specifying name and inverting. For example

$ find ./test -name 'abc*' ! -name '*.php'
./test/abc.txt
./test/abc

The above find command looks for files that begin with abc in their names and do not have a php extension. This is an example of how powerful search expssions can be build with the find command.

OR operator

When using multiple name criterias, the find command would combine them with AND operator, which means that only those files which satisfy all criterias will be matched. However if we need to perform an OR based matching then the find command has the “o” switch.

$ find -name '*.php' -o -name '*.txt'
./abc.txt
./subdir/how.php
./abc.php
./cool.php

The above command search for files ending in either the php extension or the txt extension.

Filtering by Time

To find all the files which are modified 50 days back.

$ find / -mtime 50

Find all files that were accessed in the last 50 days.

$ find / -atime 50

Find all files that were modified between 50 to 100 days ago.

$ find / -mtime +50 –mtime -100

Find files modified within the last 1 hour.

$ find /home/oracle -cmin -60

To find all the files which are modified in last 1 hour.

$ find / -mmin -60

To find all the files which are accessed in last 1 hour.

$ find / -amin -60

Filtering by Size

To find all 50MB files

$ find / -size 50M

To find all the files which are greater than 50MB and less than 100MB.

$ find / -size +50M -size -100M

The following command uses the “empty” option of the find command, which finds all files that are empty.

$ find /tmp -type f -empty

To file all empty directories use the type “d”.

$ find ~/ -type d -empty

Finding by Owner

To find file under /root directory of owner root.

$ find /root -user root

We could also specify the name of the file or any name related criteria along with user criteria

$ find /root -user root -name "*cfg"

Its very easy to see, how we can build up criteria after criteria to narrow down our search for matching files.

Find all files that belong to a particular group.

$ find /var/www -group developer

Did you know you could search your home directory by using the ~ symbol

$ find ~ -name "test.xml"

Finding by Permissions

The following command searches for files with the permission 0664

$ find -type f -perm 0664

Inversion can also be applied to permission checking.

$ find -type f ! -perm 0777

Find files with sgid/suid bits set

The following command finds all files with permission 644 and sgid bit set.

$ find / -perm 2644

Similarly use 1664 for sticky bit. The perm option also supports using an alternative syntax instead of octal numbers.

$ find / -maxdepth 2 -perm /u=s 2>/dev/null

Note that the “2>/dev/null” removes those entries that have an error of “Permission Denied”

Find all Read Only files.

$ find /etc -maxdepth 1 -perm /u=r

The following command will find executable files

$ find /bin -maxdepth 2 -perm /a=x

Executing and Combining Find Commands

We can execute an arbitrary helper command on everything that find matches by using the “-exec” parameter.

$ find find_parameters -exec command_and_params {} \;

The “{}” is used as a placeholder for the files that find matches. The “\;” is used so that find knows where the command ends.

We could find the files in the previous section that had “644” permissions and modify them to have “664” permissions.

$ find . -type f -perm 644 -exec chmod 664 {} \;

We could then change the directory permissions like this

$ find . -type d -perm 755 -exec chmod 700 {} \;

If you want to chain different results together, you can use the “-and” or “-or” commands. The “-and” is assumed if omitted.

$ find . -name file1 -or -name file9

Delete all matching files or directories

$ find /home/myftp/-type f -name *.txt -size +10M -exec rm -f {} \;

 

Linux locate command

An alternative to using find is the locate command. This command is often quicker and can search the entire file system with ease.

To find files with locate, simply use this syntax:

$ locate install.log

You can use the “-b” for only searching the “basename”.

$ locate -b install.log

To have locate only return results that still exist in the filesystem (that were not remove between the last “updatedb” call and the current “locate” call), use the “-e” flag.

$ locate -e install.log

To see statistics about the information that locate has cataloged, use the “-S” option:

$ locate -S
Database /var/lib/mlocate/mlocate.db:
13,269 directories
112,119 files
6,233,493 bytes in file names
2,700,931 bytes used to store database

Find and locate are powerful commands that can be strengthened by combining them with other utilities through pipelines. Experiment with filtering by using commands like wc, sort and grep.

Advertisements