locate
– Find files by namefind
– Search for files in a directory hierarchyxargs
– Build and execute command lines from standard inputtouch
– Change file Itemsstat
– Display file or file system status
The locate program performs a rapid database search of pathnames, and then outputs every name that matches a given substring.
$ locate bin/zip
/snap/gnome-3-38-2004/115/usr/bin/zipdetails
/snap/gnome-3-38-2004/119/usr/bin/zipdetails
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipdetails
/usr/bin/zipgrep
/usr/bin/zipinfo
/usr/bin/zipnote
/usr/bin/zipsplit
Most systems equipped with locate run updatedb
once a day. Since the database is not updated continuously, you will notice that very recent files do not show up when using locate
. To overcome this, it’s possible to run the updatedb
program manually by becoming the superuser and running updatedb
at the prompt.
While the locate
program can find a file based solely on its name, the find
program searches a given directory (and its subdirectories) for files based on a variety of attributes.
To find all files withing home directory (without any filtering criteria)
$ find ~
The beauty of find is that it can be used to identify files that meet specific criteria.
$ find ~ | wc -l
119971
Let’s say that we want a list of directories from our search (Adding the test -type d
limited the search to directories)
$ find ~ -type d | wc -l
We could have limited the search to regular files with this test
find ~ -type f | wc -l
File Type | Description |
---|---|
b | Block special device file |
c | Character special device file |
d | Directory |
f | Regular file |
l | Symbolic link |
Files that match the wildcard pattern "*.go" and are larger than one megabyte:
$ find ~ -type f -name "*.go" -size +1M | wc -l
23
The leading plus sign indicates that we are looking for files larger than the specified number. A leading minus sign would change the meaning of the string to be smaller than the specified number. Using no sign means, “match the value exactly.” The trailing letter “M” indicates that the unit of measurement is megabytes.
Char | Unit |
---|---|
k | Kilobytes (units of 1024 bytes) |
M | Megabytes (units of 1048576 bytes) |
G | Gigabytes (units of 1073741824 bytes) |
What if we needed to determine if all the files and subdirectories in a directory had secure permissions? We would look for all the files with permissions that are not 0600 and the directories with permissions that are not 0700.
$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
( file with bad perms ) -or ( directory with bad perms )
Operator | Description |
---|---|
-and | Match if the tests on both sides of the operator are true. May be shortened to -a Note that when no operator is present, -and is implied by default. |
-or | Match if a test on either side of the operator is true. May be shortened to -o. |
-not | Match if the test following the operator is false. May be abbreviated with an exclamation point (!). |
( ) | Groups tests and operators together to form larger expressions. This is used to control the precedence of the logical evaluations. By default, find evaluates from left to right. Note that since the parentheses characters have special meaning to the shell, they must be quoted when using them on the command line to allow them to be passed as arguments to find. Usually the backslash character is used to escape them. |
find
allows actions to be performed based on the search results.
Action | Description |
---|---|
-delete | Delete the currently matching file. |
-ls | Perform the equivalent of ls -dils on the matching file. Output is sent to standard output. |
Output the full pathname of the matching file to standard output. This is the default action if no other action is specified. | |
-quit | Quit once a match has been made. |
We can use find to delete files that meet certain criteria.
$ find . -type f -name '*.logus' -delete
Every file with extension *.logus
is deleted. It is always better to check the target files by using the ls
option.
$ find . -name '*.logus' -ls
791466 4 -rw-rw-r-- 1 himanshu himanshu 6 Oct 18 00:04 ./first.logus
Create 100 dir and 26 files in each one of them.
$ mkdir -p playground/dir-{001..100}
$ touch playground/dir-{001..100}/file-{A..Z}
$ find playground -type f -name 'file-A'
playground/dir-071/file-A
playground/dir-083/file-A
playground/dir-010/file-A
playground/dir-096/file-A
...
$ find playground -type f -name 'file-A' | wc -l
100
Make a reference file
$ touch playground/timestamp
$ stat timestamp
File: timestamp
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 803h/2051d Inode: 1444729 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/himanshu) Gid: ( 1000/himanshu)
Access: 2022-10-18 01:24:24.700869347 +0530
Modify: 2022-10-18 01:24:24.700869347 +0530
Change: 2022-10-18 01:24:24.700869347 +0530
Birth: 2022-10-18 01:24:24.700869347 +0530
This update all the file-B in all the directories with new timestamp.
$ find playground -type f -name 'file-B' -exec touch '{}' ';'
Get all files newer than timestamp file (return all file-B in each directory)
$ find playground -type f -newer playground/timestamp | wc -l
100