How to Find File by Content in Linux
Sometimes, you may need to find a file containing a specific string or find a line in a text file where a particular word is present. This can be useful for searching logs, locating configuration files if you don’t know where they are, or find files with source code.
In the past, the grep utility was the only tool used for these purposes It is a built-in tool in most Linux distros. However, nowadays, there is a multitude of other commands that can do it faster and are more user-friendly. In this article, we will explore some of the most interesting and useful ways of file searching and provide a few examples of how to use them.
Searching for Files by Content in Linux
All utilities provided in this article have only command line interface. So that, you need to open linux terminal before using them. In Ubuntu you can launch Terminal using Ctr+Alt+T. If you’re interested in GUI applications, go to the general article about searching for files in Linux. Most of the commands described below have a similar syntax:
$ command options pattern /path/to/folder
The search pattern can be just a word, but the commands expect it to be a regular expression. Therefore, if your query contains special characters, you may get unexpected results. By default, commands perform search in the current working directory, but it most cases you can specify the directory for search in the last argument. Now, let’s examine each command in more detail.
I will use the /etc/ directory for all examples in this article. It contains files which can be accessed only by root user, so I will use sudo to avoid encountering errors. However, if you are searching in the home directory, you don’t need to put sudo in front of the search commands.
1. Grep
Let’s take a look at the grep command before moving on to modern utilities. It is part of the GNU project and has been used for searching text in files and files by content in Linux for a long time.
By default, grep filters a single file or standard input. So that, it can filter content of a file. To perform a search in a folder across multiple files, you need to enable recursive search using the -r option. For example, let’s find all files in the /etc/ folder that contain the string «root»:
You can see sample output on the screenshot below:
The grep command does not highlight the occurrences of symbols which you searched for in color. But you can use the —color=always option to enable it. However, in most distributions, this option is already set in the alias for this command, so the output will look like this:
sudo grep —color=always -r «root» /etc/
The above command provides file list and occurrences highlighted:
If you want to print not only the line which the occurrence but also several lines before and after, you can use the -C or —context option with the number of lines to show:
As I said before, grep expects the search query to be a regular expression, but it only supports basic syntax with limited number of special characters. Use the -E option to enable extended syntax. For example, to find all files containing variables starting with the letter A in the /etc/ folder, run:
sudo grep -r -E «^A[A-Z_]+ wp-block-image»>
If you want to search for a fixed string rather than a regular expression, use the -F option or the fgrep command. For example, you can find all files containing the [Install] section in the /usr/ folder using the following command:
sudo grep -r -F «[Install]» /usr/
2. Ripgrep
Ripgrep is a popular Rust-based alternative to grep. It can do everything grep can, but it’s faster and more convenient to use. Recursive search is enabled by default, and highlighting occurrences as well as file names in different colors also works without additional options. Additionally, it skips hidden files, binary files, and files listed in .gitignore. By default it is finding files in the current directory. Also it outputs line number of occurrence by default. If you haven’t installed this utility yet, you can use the following command:
sudo apt install -y ripgrep
When you run ripgrep with any file specified, it will find and display all occurrences within it. For example:
If you provide a folder, the rg command will search in all files that are present in this folder. By default it uses the current folder. For example, use the following command to find all files containing the word «root» in the specified directory. In this case it is /etc/
Like grep, you can display not only the line with the occurrence but also several lines before and after, for example, two:
Full regular expression syntax is supported by default. For example:
sudo rg «^A[A-Z_]+ wp-block-image»>
If you need to search for a specific string, not a regular expression, use the -F option:
3. Ack
If you need to find a source code file knowing a line within it, there are more suitable utilities than grep. For example, ack. It has been around for quite some time and is designed specifically for working with source code. In addition to all the features of grep, it allows you to skip backup files, internal .git and .svn repository files, as well as memory dumps. Moreover, you can choose the types of files to be searched and even specify a particular part of a file. Also, this command is usually utilized for searching in entire file system. Use the following command to install the program on Ubuntu:
The simplest example — searching for all files containing the word «root» in the /etc/ folder:
Also you can use a regular expression. For example, let’s find files with variables starting with the letter A as well as in the previous section:
sudo ack «^A[A-Z_]+ wp-block-image»>
You can use use the -C option to display not only the line with the occurrence but also the lines before and after it. Two lines are displayed by default:
The ack command allows you to specify the type of files to search in. This is very convenient for searching source code. You can choose only C, JavaScript, or PHP source files, and etc. Use the following command to view all available file types:
For example, use the —type option with the value «xml» to search only in XML files:
sudo ack —type=xml «root» /etc/
Another interesting feature of the ack utility is the ability to select parts of files for searching using a regular expression. The —range-start and —range-end options are intended for this, and it will work within a single line as well as the entire file. For example, to search only in the comments of XML files, you can use the following command:
sudo ack —type=xml —range-start=»» «root» /etc/
4. Sliver Searcher
It is one of the most popular programs for searching text in files on Linux. It was designed as an alternative to ack, as a code-searching tool. In addition to the main features of ack, it is significantly faster and respects exclusion settings from .gitignore and .hgignore files. Use the following command to install the program on Ubuntu:
sudo apt -y install silversearcher-ag
Let’s have a look at the same example as in the previous sections. If you want to find all files containing the word «root» in the /etc/ folder, run:
Like grep and ripgrep, ag expects a regular expression as a search pattern, so you can use it without any additional options. For example:
sudo ag «^A[A-Z_]+ wp-block-image»>
But if you want the search query to be treated as a string, use the -Q option. For example, if you want to search for all files containing the [Install] section in the /usr/ folder, run:
Also you can also display several lines before and after the line with the occurrence using the -C option. Unlike grep and ripgrep, ag allows you to specify the type of files in which you want to perform the search. You can view all available file types using the following command:
For example, let’s search only in *.ini files:
The utility also allows you to use a regular expression to filter files by name before searching their content using -G option. For example, use the following command to search only in files whose names end with conf:
5. Skim
This is another interesting utility for fuzzy real-time search, written in Rust. By default, it searches for files by name, but it can be used in conjunction with one of the above-listed utilities for real-time content-based file search. The program package is not yet available in the official repositories, but you can install it using cargo:
The command performs a search only in the current folder and it is not possible to specify another folder, so you need to first navigate to the desired folder using the cd command. For example:
Then use the following command to combine it with Silver Searcher for content filtering:
Here, the —ansi option enables colored output, -i enables interactive mode, and the -c option sets the command that will be executed when you enter any query, the string <> will be replaced with what you enter during the search. Simply run the command and start typing the word you want to search for:
After this, you can use all the fuzzy search filtering features to process the results.
Performance of grep, rg, ack and ag
At the end I want to show a small performance test of the aforementioned utilities for searching text in files on Linux. I downloaded and extracted the source code of the Linux kernel version 6.2.10, and then used each of the utilities to find all files containing the words ext4 and btrfs. Between different utilities, the system was rebooted to eliminate the influence of caching.
Command | Time, sec | Command | Time, sec |
grep -r ext4 ./ | 23.167 | grep -r btrfs ./ | 3.860 |
rg ext4 ./ | 27.164 | rg btrfs ./ | 1.387 |
ack ext4 ./ | 36.141 | ack btrfs ./ | 7.206 |
ag ext4 ./ | 24.594 | ag btrfs ./ | 3.158 |
As you can see, after the system statup, all commands perform roughly the same. However, all utilities written in Rust make more efficient use of caching, as they work faster than their C counterparts when launched repeatedly for the same set of files.
Wrapping Up
In this article, we have reviewed the most commonly used utilities for searching files by content in Linux and searching text in files. As you can see, there are enough tools to choose from. All the commands are quite similar, but each has its own features. What do you use? Let us know in the comments!
Found a mistake in the text? Let me know about that. Highlight the text with the mistake and press Ctrl+Enter.
How can I do a recursive find and replace from the command line?
Using a shell like bash or zshell, how can I do a recursive ‘find and replace’? In other words, I want to replace every occurrence of ‘foo’ with ‘bar’ in all files in this directory and its subdirectories.
It might be a good idea to try this in vim. That way you can use the confirmation feature to make sure you don’t swap something you don’t intend to. I am not sure if it can be done directory wide.
10 Answers 10
This command will do it (tested on both Mac OS X Lion and Kubuntu Linux).
# Recursively find and replace in files find . -type f -name "*.txt" -print0 | xargs -0 sed -i '' -e 's/foo/bar/g'
- find . -type f -name ‘*.txt’ finds, in the current directory ( . ) and below, all regular files ( -type f ) whose names end in .txt
- | passes the output of that command (a list of filenames) to the next command
- xargs gathers up those filenames and hands them one by one to sed
- sed -i » -e ‘s/foo/bar/g’ means «edit the file in place, without a backup, and make the following substitution ( s/foo/bar ) multiple times per line ( /g )» (see man sed )
Note that the ‘without a backup’ part in line 4 is OK for me, because the files I’m changing are under version control anyway, so I can easily undo if there was a mistake.
To avoid having to remember this, I use an interactive bash script, as follows:
#!/bin/bash # find_and_replace.sh echo "Find and replace in current directory!" echo "File pattern to look for? (eg '*.txt')" read filepattern echo "Existing string?" read existing echo "Replacement string?" read replacement echo "Replacing all occurences of $existing with $replacement in files matching $filepattern" find . -type f -name $filepattern -print0 | xargs -0 sed -i '' -e "s/$existing/$replacement/g"