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.
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.
0 Comments