Learn Linux 17: Searching

Published Jan 18, 2022

Contents


Introduction

As we have wandered around our Linux system, one thing has become abundantly clear: a typical Linux system has a lot of files! This raises the question, "How do we find things?" We already know that the Linux file system is well organized according to conventions passed down from one generation of Unix-like systems to the next, but the sheer number of files can present a daunting problem. This chapter will introduce the following commands:

  • locate - Find files by name
  • find - Search for files in a directory hierarchy
  • xargs - Build and execute command lines from standard input
  • touch - Change file times
  • stat - Display file or file system status

locate: Find Files The Easy Way

The locate program performs a rapid database search of pathnames and then outputs every name that matches a given substring. Say, for example, we want to find all the programs with names that begin with zip. Because we are looking for programs, we can assume that the name of the directory containing the programs would end with bin/. Therefore, we could try to use locate this way to find our files.

[user@linux ~]$ locate bin/zip
/usr/bin/zip
/usr/bin/zipcloak
/usr/bin/zipgrep
/usr/bin/zipinfo/usr/bin/zipnote
/usr/bin/zipsplit

You might notice that, on some distributions, locate fails to work just after the system is installed, but if you try again the next day, it works fine. What gives? The locate database is created by another program named updatedb. Usually, it is run periodically as a cron job, that is, a task performed at regular intervals by the cron daemon. Most systems equipped with locate run updatedb once a day. Because 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.

find: Find Files The Hard Way

In its simplest use, find is given one or more names of directories to search. For example, to produce a listing of our home directories, we can do the following.

[user@linux ~]$ find ~

Because the list is sent to standard output, we can pipe the list into other programs.

[user@linux ~]$ find ~ | wc -l

Here is some examples of find with different options.

File Type

  • b - Block special device file.
  • c - Character special device file.
  • d - Directory.
  • f - Regular file.
  • l - Symbolic link.
[user@linux ~]$ find ~ -type d | wc -l

Size Unites

  • b - 512-byte blocks. This is the default if no unit is specified.
  • c - Bytes.
  • w - 2-byte words.
  • k - Kilobytes.
  • M - Megabytes.
  • G - Gigabytes.
[user@linux ~]$ find ~ -type f -name "*.JPG" -size +1M | wc -l

Operators

  • -and
  • -or
  • -not
  • ()
[user@linux ~]$ find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -prem 0700 \)

Actions

  • -delete - Delete the currently matching file.
  • -ls - Perform equivalent of ls -dils on the matching files. output is sent to standard output.
  • -print - This is the default action.
  • -quit - Quit once a match has been made.
[user@linux ~]$ find ~ -type f -name '*.foo' - delete

User Defined Actions

  • The traditional way of doing this is with the -exec action.
  • This command is an example of using -exec to act like the -delete action.
  • {} is a symbolic representation of the current pathname
  • ; and the semicolon is a required delimiter indicating the end of the command.
  • Again because the brace and semicolin characters have special meaning to the shell, they must be quoted or escaped.
[user@linux ~]$ find ~ -type f -name '*.foo' -exec rm '{}' ';'
[user@linux ~]$ find ~ -type f -name 'out*' -exec ls -la '{}' ';'

Improving The Efficiency Of User Defined Actions

When the -exec action is used, it launches a new instance of the specified command each time a matching file is found. There are times when we might prefer to combine all of the search result and launch a single instance of the command. For example rather than executing the coomand like this:

[user@linux ~]$ ls -l file1
[user@linux ~]$ ls -l file2

We may prefer to execute them this way:

[user@linux ~]$ ls -l file1 file2

To achive this we need to use the + sign instead of the ; sign.

[user@linux ~]$ find ~ -type f -name 'out*' -exec ls -la '{}' +

xargs

The xargs command accepts input from standard input and converts it into an argument list for a specified command.

[user@linux ~]$ find ~ -type f -name 'foo*' -print | xargs ls -la

Summary

It’s easy to see that locate is as simple as find is complicated. They both have their uses. Take the time to explore the many features of find. It can, with regular use, improve your understanding of Linux file system operations.