قالب وردپرس درنا توس
Home / Tips and Tricks / Using the grep command on Linux

Using the grep command on Linux



  A terminal prompt on a Linux PC.
Fatmawati Achmad Zaenuri / Shutterstock

The Linux command grep is a string and pattern matching utility that displays matching rows from multiple files. It also works with pipe output from other commands. We'll show you how.

The story behind grep

The command grep is known in Linux and Unix circles for three reasons. First, it is extremely useful. Second, the wealth of options can be overwhelming. Third, it was written overnight to meet a specific need. The first two are tough; The third is a little different.

Ken Thompson had extracted the search functions for regular expressions from the ed editor (pronounced ee-dee) and created a small program for searching text files for his own use. His department manager at Bell Labs, Doug Mcilroy, contacted Thompson and described the problem one of his colleagues, Lee McMahon, was facing.

McMahon attempted to identify the authors of the federalist articles through text analysis. He needed a tool to search for phrases and strings in text files. Thompson spent about an hour that evening making his tool a general utility that could be used by others and renamed it grep . He took the name from the ed command string g / re / p which is translated as "global search for regular expressions".

You can talk to Brian Kernighan about the birth of grep Thompson.

Simple search with grep

Enter the search term and the file name on the command line to search for a character string in a file:

  grep dave / etc / Password in a terminal window 

Matching lines are shown. In this case, it is a single line. The appropriate text is highlighted. This is because most distributions grep as an alias

  grep = & # 39; grep --colour = auto & # 39; 

Results with multiple matching rows are displayed. The word "average" is searched for in an application log file. Since we cannot remember whether the word in the log file is in lower case, we use the option -i (case insensitive):

  grep -i Average geek-1.log [19659014]   grep -i Average geek-1.log in a terminal window  

Each matching line is displayed with the matching text highlighted.

 Output of grep -i Average geek -1.log in a terminal window.

With the option -v (reverse match), rows that do not match can be displayed.

  grep -v Mem geek-1.log 

 grep -v Mem geek-1.log in a terminal window

There are no highlights because these are the mismatched lines.

 Output of grep -v Mem geek-1.log in a terminal window

We can leave grep completely silent. The result is passed to the shell as a return value from grep . A result of zero means that the string was found and a result of one means that it was not found . We can use the special parameters $? check:

  grep -q average geek-1.log 
  echo $? 
  grep -q howtogeek geek-1.log [19659026] echo $? 

 grep -q average geek-1.log in a terminal window

Recursive search with grep

Use the -r (recursive) option to search nested directories and subdirectories. Note that you do not have to enter a file name on the command line, you must specify a path. Here we search in the current directory "." And in all subdirectories:

  grep -r -i memfree. 

 grep -r -i memfree. in a terminal window

The output contains the directory and the file name of each matching line.

 Edition of grep -r -i memfree. in a terminal window

With the option -R (recursive dereferencing) we can have grep follow symbolic links. In this directory there is a symbolic link called logs-folder . It refers to / home / dave / logs .

  ls -l logs-folder 

 ls -l logs-folder in a terminal window

Let's repeat our last search with the option -R (recursive dereferencing) :

  grep -R -i memfree. 

 grep -R -i memfree. in a terminal window

The symbolic link is followed and the directory to which it refers is also searched by grep .

 Edition of grep -R -i memfree. in a terminal window

Search for whole words

By default, grep matches a line if the search target is displayed anywhere on this line, even within another string. Take a look at this example. We will look for the word "free".

  grep -i free geek-1.log 

 grep -i free geek-1.log in a terminal window

The result is lines in which the string is "free", however, they are not separate words. They are part of the "MemFree" string.

 Output of grep -i free geek-1.log in a terminal window

To force grep to match separately Use only the -w [option (word regexp).

  grep -w -i free geek-1.log 
  echo $? 

 grep -w -i free geek-1.log in a terminal window

This time there were no results because the search term "free" does not appear in the file as a separate word.

Use multiple search terms [19659005] With the option -E (extended regular expression) you can search for several words. (The -E option replaces the outdated egrep version of grep .)

This command searches for two keywords, "average" and "memfree" , ”

  grep -E -w -i" Average | memfree "Geek-1.log 

 grep -E -w -i" Average | memfree "Geek-1.log in a terminal window

All matching rows are displayed for each search term.

 Output of grep -E -w -i "average | memfree" geek-1.log in a terminal window

You can also search for several terms that are not necessarily whole Words are concerned, but they can also be whole words.

With the option -e (pattern) you can use multiple search terms for the command line. We use the regular expression bracket function to create a search pattern. It instructs grep to match one of the characters contained in the brackets "[]". This means that grep matches either “kB” or “KB” when searching. [19659006]   grep -e MemFree -e [kK] B geek-1.log in a terminal window

Both strings match, and in fact some lines contain both strings.

   Edition of grep -e MemFree -e [kK] B geek-1.log in a terminal window 

Exactly matching lines

The -x (line regexp) fits only for lines where the entire line matches the search term. Let's look for a date and time stamp that we know only appears once in the log file:

  grep -x "Jan 20-6 3:24:35 pm" geek-1.log [19659014]  grep -x "20-Jan - 06 15:24:35" geek-1.log in a terminal window  

The matching single line is found and displayed.

The opposite of this is only shown the lines that do not match . This can be helpful when looking at configuration files. Comments are great, but sometimes it's difficult to see the actual settings in all of them. Here is the file / etc / sudoers :

 Contents of the / etc / sudoers file in a terminal window

We can effectively filter out the comment lines as follows: [19659013] sudo grep -v "#" / etc / sudoers

 sudo grep -v

This is much easier to analyze.

Show matched text only

There may be an occasion if you don't want to see the entire matched line, just the matched text. The option -o (only suitable) does exactly that.

  grep -o MemFree geek-1.log 

 grep -o MemFree geek-1.log in a terminal window

Instead of the entire matching line, the display only shows the text that matches the search term.

 Output of grep -o MemFree geek-1.log in a terminal window

Counting with grep

grep is not just about text, it can also contain numerical information deliver. We can have grep count for us in different ways. If you want to know how often a search term occurs in a file, you can use the option -c (count).

  grep -c average geek-1.log 

] grep -c average outsider-1.log in a terminal window

grep reports that the search term 240 times in this file.

You can grep Show the line number for each matching line with the option -n (line number).

  grep -n Jan geek-1.log 

 grep -n jan geek -1.log in a terminal window

The line number for each matching line is displayed at the beginning of the line.

 Output of grep -n jan geek-1.log in a terminal window

To reduce the number of results displayed, use the option -m (maximum Number). We limit the output to five matching lines:

  grep -m5 -n Jan geek-1.log 

 grep -m5 -n Jan geek-1.log in a terminal window

Add of context

It is often useful to be able to display some additional lines - possibly non-matching lines - for each matching line. It can be helpful to distinguish which of the matching rows are of interest to you.

Use the -A (by context) option to display a few lines after the matching line. In this example three lines are queried:

  grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log 

 grep -A 3 -x [19659006] To display a few lines before the matching line, use the option -B (context before).

  grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log 

 grep -B 3 -x

Use the option -C (context) to include lines before and after the matching line.

  grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log 

 grep -C 3 -x

Show matching files [19659005] Use the -l (matched files) option to display the names of the files that contain the search term. Use this command to find out which C source code files contain references to the header file sl.h :

  grep -l "sl.h" * .c 

 grep - l "sl.h" * .c in a terminal window

The file names are listed, not the matching lines.

 Output of grep -l "sl.h" * .c in a terminal window

And of course we can search for files that do not contain a search term. The -L (files mismatch) option does just that.

  grep -L "sl.h" * .c 

 grep -L "sl.h" * .c in a terminal window

beginning and end of lines

We can force grep to only display matches that are either at the beginning or at the end of a line. The regular expression operator "^" matches the beginning of the line. Virtually all lines in the log file contain spaces, but we will look for lines whose first character contains a space:

  grep "^" geek-1.log 

 grep "^" geek-1.log in a terminal window

The lines whose first character - at the beginning of the line - contains a space are displayed.

 Output grep "^" geek-1.log in a terminal window

Use the operator "$" for regular expressions to match the end of the line. We will look for lines that end with "00".

  grep "00 $" geek-1.log 

 grep "00 $" geek-1.log in a terminal window

The display shows the lines whose end characters "00" are.

 Output of grep "00 $" geek-1.log in a terminal window

Using pipes with grep

Of course you can direct input to grep that Direct output of grep to another program and have grep embedded in the middle of a pipe chain.

Suppose we want to show all occurrences of the string "ExtractParameters" in our C source code files. We know there will be some, so we redirect the edition to less :

  grep "ExtractParameters" * .c | less 

 grep "ExtractParameters" * .c | less in a terminal window

The output is in less .

 Edition of grep "ExtractParameters" * .c | less in a terminal window

Lets you scroll through the file list and use the search function of less .

If we output grep to wc and use the -l (lines) option to count the number of lines in the source code files that contain "ExtractParameters". (We could do this with the grep -c (count) option, but this is a good way to demonstrate the piping of grep .)

  grep " ExtractParameters "* .c | wc -l 

 grep "ExtractParameters" * .c | wc -l in a terminal window

With the next command we route the edition of ls to grep and the edition of grep in sort . We list the files in the current directory, select them with the string "Aug" and sort them by file size:

  ls -l | grep "Aug" | sort + 4n 

 ls -l | grep

Let's take this apart:

  • ls -l : List the files in long format with ls .
  • grep “Aug” : Select the lines from the ls list that contain "Aug". Note that this will also find files with the name "Aug".
  • sort + 4n : Sort the output from grep in the fourth column (file size).

We get a sorted list of all files files that were changed in August (regardless of the year) in ascending order of file size.

RELATED: Using Pipes on Linux

grep: Less a Command, More of an Ally

grep is an excellent tool that You must have available. It dates back to 1974 and is still strong because we need what it does and nothing can do it better.

Coupling grep with some regular expressions really takes it to the next level.

RELATED: Using basic regular expressions for better searching and saving time




Source link