This article describes how to search for files in bash, and shows a few examples of using find, grep, and ag (the silver searcher).

Search for files in bash

People using bash on a daily basis know at least two basic tools for searching: find and grep. The main difference is that find is for searching based on file properties, while grep is a tool for searching text content via regexp.

There are other two search tools used by developers that are worth to mention: ack and ag. Both are developer-friendly tools to search for textual contents, but ag (the silver searcher) is much more performant.

In the rest of the article, we’re going to see bash search examples for the following tools:

  • find : search files by properties, i.e. by name, size, last modified, etc.
  • grep/egrep : search file contents by a regular expression.
  • ag (the silver searcher): a developer-friendly tool to search files by content.

Search files by extension

Say we search for .adoc files in the ~/git directory, and we want to list only the files modified in the last 30 days. For this purpose, we can use the find command as you see in the snippet below.

find ~/git/ -type f -name '*.adoc' -mtime -30

Here is a description of some of the non-obvious parameters.

  • -type f denotes files
  • -mtime -30 means modified in the last 30 days

Search files by content

When searching for files with specific text content, we might want to use grep (or egrep). For example, the command below search for all the .adoc files containing either the text bash or .sh.

egrep --color -rnw ~/git/ --include='*.adoc' -e 'bash|\.sh'

Some of the options are not straightforward. Below, you see a description for some of them.

  • --color: highlight matching result
  • -rnw: recursive, line number, match the whole word
  • --include : match specific files
  • -E : extended regexp, allows usage of | for logical OR.

Search files by properties and content

When you are searching files both by file properties and text content, you can combine the usage of find and grep.

As an example, we search for all the *.adoc files modified in the last 30 days containing bash or .sh. To do so, we can combine the results of find with the regexp search, as you see in the snippet below.

find ~/git/ -type f -name '*.adoc' -mtime -30 -exec egrep --color -nw -e 'bash|\.sh' {} +

The command above looks complex to understand. However, compared to the commands seen before the main difference is in a few parameters:

  • find’s -exec <command> {} + executes the command in the same way as xargs does, and it is POSIX compliant.
  • egrep’s --color highlight the regexp match

List files by properties and content, from multiple dirs with excludes

Here we see a small example of composing the find command with grep, by excluding some directories from the search.

List names of *.adoc files containing the word sudo searching in multiple dirs, but excluding a specific path.

find ~/git/ ~/gdrive/ ~/Desktop/ -not -path "~/git/asciidoctor*" -type f -name '*.adoc' -exec grep -lw -E 'sudo' {} +
  • multiple dirs (note: if you have dirs with spaces use \ (slash space)
  • grep -wl: match the whole word, and list files only (don’t show match in files)

Ag, the silver searcher

Ag, the Silver Searcher, is a search tool similar to ack. It is a quite powerful and fast command-line tool for developers to search for files. See some examples below.

Search for a specific text in files in three different cases: with no constraints, within a specific directory, and by filtering by file extension. You can see a few examples in the snippets below.

# search recursively in all files starting from current dir
ag wordpress
# in all files under ~/git/
ag wordpress ~/git/
# in all files with name matching yml under ~/git/
ag wordpress -G yml ~/git/

The Silver Searcher provides additional advanced options, such as searching for a specific word, ignoring paths during the search, and searching by boolean OR inclusion. See the examples in the snippet below.

# search for the exact word
ag -w wordpress ~/git/
# search but exclude specific files
ag wordpress ~/git/ --ignore={'*.json','*.html'}
# search for 'wordpress' or '.local'
ag 'wordpress|\.local' ~/git/

By default, the output shows both the file names and the lines matching the search, where the match is highlighted, as you see in the image below.

bash output for a search using ag (the silver searcher)

To display the matching filenames only, you can use the -l option, as you see in the image below.

# output filenames only
ag -l wordpress -G yml ~/git/

Below, you see a few notes about ag, including the description of a few parameters.

  • by default ag ignore files that are ignored in .gitignore
  • -G search only in files with matching names
  • -w search for the whole word
  • -l list files only, don’t show matches
  • --ignore for patterns: both files and directories

On mac os, you can install Ag with brew install ag. Similarly, you can install it on other Linux versions using their package manager.

References


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *