1. Overview

The grep (global regular expression print) utility is a powerful command-line tool. It can be used to search for text patterns in files, variables, and the output of commands. When combined with Bash variables, grep becomes a versatile tool for text processing and data extraction in scripts.

In particular, grep can be useful for a variety of tasks:

  • checking if a variable contains a specific value
  • finding all the lines in a file that contain a specific string
  • filtering the output of a command based on a text pattern

In this tutorial, we’ll see how to create Bash variables, the basic usage of grep, and how to combine both concepts.

2. Creating Bash Variables

To demonstrate how grep works with Bash variables, we first define a variable in Bash. In general, there are two types:

Let’s start by creating a user-defined Bash variable. User-defined variables can be created by simply assigning a value to them with the = equals sign, for example:

$ a=5
$ B=55
$ string_example="It's a string."
$ variable_description=SomeName

Here, a, B, string_example, and variable_description are the names of the variables. In contrast to several programming languages, Bash exhibits an indifference toward the type of data assigned to variables; it assumes all variables as strings.

Thus, values assigned to the above variables are all strings.

Furthermore, we can interpolate a variable with a $ dollar prefix before its name, for instance:

$ echo $a

The echo command prints the value of the variable a, which is 5 in this case.

3. grep and Bash Variables

After discussing how to create a Bash variable, we’ll now see how to use grep with them. Let’s start with a basic use case: searching for a specific word within a file.

Let’s take .bashrc as our sample file. Further, we define a variable alias_command:

$ alias_command=alias

The variable alias_command is assigned the value alias in reference to the alias command. We can now use grep to check whether this text exists in the .bashrc file:

$ grep $alias_command ~/.bashrc
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'
    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'

The above command searches the .bashrc file for any lines that include the word alias. It then displays those lines as output to the terminal.

Moreover, we can also check if a string with whitespace assigned to a variable exists in a file. For this, we first set another Bash variable:

$ alias_list_command="alias l"

Now, the variable alias_list_command holds a string. Next, we use double quotes around the variable alias_list_command to search for the string in the .bashrc file:

$ grep "$alias_list_command" ~/.bashrc
alias ls='ls --color=auto'
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

Here, the shell interpolates the alias_list_command variable inside the double quotes. Then, grep searches the .bashrc file for any lines that contain the text alias l. Finally, the matched lines are displayed.

These basic use cases enable us to perform simple checks within a file’s content.

4. Reading From Standard Input

grep can also read data from the standard input. Usually, the input comes from the output of some inline command. To demonstrate this, let’s use an example.

Let’s suppose we want to search for a text in the content of a variable. For this, we can use a pipe operator and the echo command with grep.

For example, we declare a user-defined variable containing a string:

$ sample_text="This is a sample text with some keywords."

Now, we can search for text that contains the character s within the variable sample_text:

$ echo "$sample_text" | grep "s"
This is a sample text with some keywords.

Here, the output from the echo command is read by the grep command. Consequently, grep prints each string or text containing the character s. If the terminal supports color, we can see the character highlighted in red.

Moreover, if we’re interested in looking only at the matched pattern within words instead of whole strings, we can replace spaces with newlines before grepping:

$ echo "$sample_text" | tr ' ' '\n'| grep "s"
This
is
sample
some
keywords.

The tr command we add to the pipeline replaces the spaces around the text with the newline character (\n). This prints only the matched words on new lines.

5. Usage With a Here String

Another handy method is to use a here string with the grep command. This approach enables us to directly feed the variable’s content to grep without using the echo command.

Let’s define a new variable, here_string_demo, to hold a string:

$ here_string_demo="Here, this is a here string demo with grep."

Thereafter, we search for the text here inside the string stored in here_string_demo:

$ tr ' ' '\n' <<< "$here_string_demo" | grep -i "here"
Here,
here

Here, <<< is the here-string operator. Notably, it sends the content of here_string_demo to tr. After removing the surrounding spaces and inserting a newline character, tr passes the output to grep. The grep command then filters the output based on the input string.

6. Usage With Regular Expressions

One of the advantages of grep is its support for regular expressions (regex). Consequently, we can search for more complex text patterns within a variable by using grep regex.

Regular expressions are used in slightly different forms by different languages. Here, we’ll see only how grep uses its default regex syntax for lookup patterns.

To begin with, we create a new variable that holds the contents of the file  /etc/passwd:

$ passwd_contents="$(cat /etc/passwd)"

Let’s suppose we want to look for the lines containing /bin but not /sbin:

$ echo "$passwd_contents" | grep "/[^s]bin"

Here, we’ve used a character class or group by leveraging the square brackets. Basically, it matches a set of characters within the square brackets against a given string.

Also, we put the ^ caret character at the start of the group to invert the match to all characters except those inside the square brackets. In this case, we want to match /.

As a result, the above code shows all the entries containing only the /bin directory from the content of passwd_contents.

7. Counting a Sequence

So far, we’ve only seen how to look for a specific string in a variable. Interestingly, we can also count the number of occurrences of a specific pattern in that variable.

Let’s take the case of the passwd file assigned to passwd_contents. To count the occurrences of the string */*bin in the file, we can use a new variable, count, to store the count:

$ count="$(grep -o "/bin" <<< "$passwd_contents" | wc -l)"

Here, we used command substitution to capture the output of the commands. In this example, the here-string operator sends the content of passwd_contents to grep. Then, grep searches for the literal string */*bin using the option -o. Further, the output is sent to wc -l as an input, so we get the number of output lines.

Thus, **the number of times /bin* was found in the content of $passwd_contents is stored inside *count.

Then, we use the echo command to display the result:

$ echo "The text bin appears $count times."
The text bin appears 58 times.

This enables us to count how often */*bin appears in passwd_contents.

8. Conclusion

In this article, we learned how to use Bash variables with the grep command. We’ve discussed different use cases.

First, we saw the basics of creating Bash variables. Second, we learned how to pass a Bash variable as an input to grep. Thus, grep reads from the standard input. Then, we looked at how to incorporate here strings and regular expressions to work with Bash variables and the grep command.

Finally, we calculated the count of a matched pattern using grep and a Bash variable.