GREP - A Practical Guide 🚀
Tags: bash, terminal, linux, learning
Published: 2024-02-11 11:47:28

Problem:
As a developer, you need to efficiently search through log files to find specific API requests or errors, but manually scanning through the logs is time-consuming and error-prone.

Solution:
Utilize the grep command in the terminal to search for API requests within log files. 

**Examples are mostly based on API logs but can be used with any file.**
**If you want to go throw all commands live - [Git Clone Terminal/Grep](https://github.com/priya-jain-dev/Terminal)**

## #Basics of Grep 📝
The basic syntax for grep is:
```bash
grep "pattern" file 
```
where:
`pattern` is the regular expression you want to search for
`file` is the name of the file you want to search

Grep works on all Unix-like systems.

Grep will print each line in the file that matches the regular expression.

By default, grep is case-sensitive, so "gnu" is different from "GNU" or "Gnu." You can make it ignore capitalization with the --ignore-case option.

### 1. Search for a pattern within a file

```bash
# grep "search pattern" path/to/file
grep "error" api_server.log
```
<img src="https://i.imgur.com/f8csa5A.png" alt="Grep search in file"/>


### 2. Search stdin for lines that do match a pattern
Many times we want to pipe Grep with another command.
```bash
# cat path/to/file | grep "search_pattern"
cat api_server.log | grep error
```
<img src="https://i.imgur.com/CjSPdse.png" alt="Grep search with cat"/>

### 3. Search pattern in multiple files in the current directory with .txt extension

```bash
cd logs
# grep "search pattern" *.txt
grep ERROR *.txt
```
<img src="https://i.imgur.com/FZihllO.png" alt="Grep search in dir"/>

## Most Important Flags 🚩

### `-i`
Grep default is case-sensitive. Use this flag to make it search case-insensitive.
```bash
grep error api_server.log -i
```
<img src="https://i.imgur.com/5AdHfgi.png" alt="Grep search case-insensitive"/>

### `-v` 
Invert the match, print all lines where the pattern does not match.

```bash
grep INFO api_server.log -v
```
<img src="https://i.imgur.com/StKDLkk.png" alt="Grep search invert"/>

### `-w`
Search for the whole word. Sometimes there is a relative pattern match but we want an exact word. In that case, this flag is useful.
```bash
grep INFO api_server.log -w
```
<img src="https://i.imgur.com/ZXgjYGD.png" alt="Grep search without -w"/>
<img src="https://i.imgur.com/TnnwkUr.png" alt="Grep search with -w"/>


### `-n`
Show line numbers along with matching lines.
```bash
grep POST api_server.log -n
```
<img src="https://i.imgur.com/ZQKD3es.png?1" alt="Grep search with line number"/>


### `-l`
Find file names that match the pattern.

```bash
#grep "pattern" *.ext -l 
grep ERROR *.txt -l
```

<img src="https://i.imgur.com/xcZjmnp.png?1" alt="Return file name where pattern match"/>

### `-R`
If you only know the folder name and it contains subdirectories, you must retrieve all file names and then search recursively within the directories.

```bash
grep ERROR -l -R
```
<img src="https://i.imgur.com/KgAiGcq.png?1" alt="Recussive search"/>


### `-o`
Only print the matching part of the line (not the whole line)

```bash
grep "Internal Server Error" api_server.log -o
```
<img src="https://i.imgur.com/r2doEEW.png?1" alt="-o in Grep"/>



### `-c`
Let's say you have one deprecated API now you want to track how many users still use it throw logs. This flag will return the count.
```bash
grep "/api/v1/deprecated" api_server.log -c
# In multiple files
grep "/api/v1/deprecated" ./logs/*.txt -c
```
<img src="https://i.imgur.com/eSb27Qi.png?1" alt="-c in Grep"/>
<img src="https://i.imgur.com/OKCcGNf.png?1" alt="-c in Grep in multiple files"/>

### `-E`
Interpret the pattern as an extended regular expression.
```bash
grep -E "user_id=[0-9]{4}" api_server.log
```
<img src="https://i.imgur.com/7KA2Eme.png?1" alt="-c in Grep"/>

## Line Context Search 🔍
### `-A`: (Lines Above)
To display the line containing the error and the line directly preceding it, you can use -A 1:
Example:
<img src="https://i.imgur.com/EZd37B9.png" alt="-A in Grep"/>

### `-B`: (Lines Below)
Continuing from the previous example, to display the line containing the error and the line directly following it, you can use -B 1:
Example:
<img src="https://i.imgur.com/6BaO55k.png" alt="-B in Grep"/>

### `-C`:  (Lines Containing)
To display the line containing the error and the lines directly above and below it, you can use -C 1:
Example:
<img src="https://i.imgur.com/X59HdC3.png" alt="-C in Grep"/>



## # Real Life Examples 💡
If you're not familiar with REGEX, I'll explain it next.

### Codebase Exploration:
I know we have a vs-code search. But searching through the terminal creates a great impression 😎

```bash
grep -r "getUserById" ./
```

### Parsing and Extracting Information

```bash
grep -o -E "User: (\w+) performed action: (\w+)" user_log.log
```
This command uses a regular expression to capture user names and their corresponding actions.

```bash
User: Alice performed action: login
User: Bob performed action: view_profile
User: Alice performed action: post_comment
User: Charlie performed action: login
User: Alice performed action: view_profile
User: Bob performed action: post_comment
```

### Pipe with another command to extract data
```bash
docker ps | grep -oE '^[0-9a-f]+'
```
This will output a list of container IDs for all running Docker containers.
```bash
f9e5f041b25a
2ab9d3fc5f8e
```

## # Advance REGEX Search 🧠

### Search for any four consecutive digits in api_server.log
```bash
grep -E "user_id=[0-9]{4}" api_server.log
```

### Matching Words Starting with 'A' or 'B':

```bash
grep -E '\b[A-Ba-b]\w+\b' api_server.log
```
<img src="https://i.imgur.com/OB84Ji9.png" alt="-C in Grep"/>

### Match either/or 

```bash
grep '400\|500' api_server.log|
```
<img src="https://i.imgur.com/mEVD7HY.png" alt="-C in Grep"/>

## Bonus Tip ✨
If you have big files:
Ripgrep is much faster than grep.
```bash
# Install
sudo apt-get install ripgrep
#or
brew install ripgrep
# Syntax 
rg <search_pattern> <filename>

```
### Blog Link
https://www.priya.today/blogs/grep


## Conclusion
In conclusion, `grep` is a powerful tool that enables users to search, filter, and manipulate text data efficiently from the command line. Mastering `grep` can significantly enhance productivity and streamline text processing tasks in the terminal environment.

***Happy Coding 👩‍💻***