find vs. grep: a mini cheat sheet
Tags: linux, bash, cli, productivity
Published: 2022-06-17 13:51:15


`grep` and `find` are such powerful commands to find resources quickly. The syntax is convenient and you can combine options at will to filter results.

## `grep`

GREP stands for "global regular expression print" and is helpful to search chars and patterns, and filter information in big chunks of data.

### 7 Basic commands

#### 1. search term (case insensitive)

```grep -i "mimiKAtZ" security.log```

#### 2. display line numbers

```grep -n "mimikatz" security.log```

#### 3. search in dir 

```grep -r "mimikatz" ./```

#### 4. exact matches 

```grep -w "h4ck3r" security.log```

#### 5. count results 

```grep -c "h4ck3r" security.log```

#### 6. get filenames only

```grep -l "h4ck3r" ./mydir```

#### 7. reverse the pattern 

```grep -v "RTFM" README.md```

### Common Options

Be aware it's not an exhaustive list:

Purpose | option
---|---
count lines that match a pattern | `-c` 
lines but not filenames | `-h`
case insensitive | `-i`
filenames only | `-l`
pass multiple expressions | `-e expression -e expression2`
patterns from file, one per line | `-f file`
line numbers | `-n`
lines that DO NOT MATCH pattern | `-v`
exact match | `-w`
pass regex | `-E`

### 7 Advanced usages

#### 1. grep in multiple files 

```grep "h4ck3r" 1.log 2.log 3.log .4log```

#### 2. exclude file extensions 

```grep -rl --exclude=*.{sh,txt} ./```

#### 3. exclude dirs 

```grep -r --exclude-dir={root,log,proc,sys} "test" ./```

#### 4. include specific file extension

```grep -nr "eth0" --include="*.conf" /etc/```

#### 5. only target lines that start with alphanumeric chars 

```grep "^[[:alnum:]]" README.md```

#### 6. another way for exact matches (`-w`) 

`grep "\bsudo\b" /etc/`

#### 7. quickly list php files (common usage):

```ls | grep ".php"```

### 7 Nice tricks

#### 1. multiple searches at the same time 

```grep -E "^(sudo|root|system)" /etc/```

#### 2. grep is taking too long? time it! 

```time grep "e" ./```

#### 3. pipe grep to narrow searches

```grep "[nN]urse" romeo-and-juliet.txt | grep -v "\[_.*Nurse.*_]"```

Source: https://www.shell-tips.com/linux/grep/#how-to-grep

#### 4. search in all derivatives of an expression (lov)

```grep -i "\blov.\+\b" romeo-and-juliet.txt```

Source: https://www.shell-tips.com/linux/grep/#how-to-grep

#### 5. pipe grep output to another program

```grep -rA 2 "bin/.*sh" ~/scripts | less```

Source: https://www.shell-tips.com/linux/grep/#how-to-grep

#### 6. grep in big `.gz` files without opening them

```zgrep -ic "h4ck3r" logs.gz```

#### 7. shorten ranges in grep searches

```grep {1..7} error.log```

### Simple or double quotes for search terms?

It depends on what you want to achieve, but in case you need to use a shell variable, which is a pretty common usage, use double quotes.

### How to highlight search terms with colors?

It's usually handled by the system itself, but if it's not the case, you can use the following alias in your `.bashrc`:

```
alias grep='grep --color=auto'
```

### Commands for hackers

Go check [hacktricks](https://book.hacktricks.xyz/linux-hardening/useful-linux-commands#greps)

## `find`

`find` is a command-line utility you can use to search a list of files or directories and apply functions on them.

### 7 basic commands

#### 1. find a file 

```find ./ myfile.json```

#### 2. find a file by its name 

```find ./mydir -name myfile```

#### 3. case insensitive search 

```find ./mydir -iname mYfILE```

#### 4. find directories within a dir 

```find ./mydir -type d```

#### 5. find in multiple dirs by filename 

```find ./mydir /mydir2/subdir -type f -name myfile```

#### 6. exclude name "README"

```find ./mydir -not README```

#### 7. find and delete JSON files 

```find ./mydir –name "*.json" –delete```

### Common Types

Purpose | type
---|---
`d` | directory
`f` | file 

### Size units

Symbol | Unit
---|---
`G` | gigabytes
`M` | megabytes
`k` | kilobytes. 
`c` | bytes (default)

### 7 advanced usages

_N.B.: When I write `-/+`, it means either `-` for smaller or `+` for bigger than. Don't use the `/`_

#### 1. find by size 

```find ./mydir -size 1M```

#### 2. find by size smaller/bigger than 

```find ./mydir -size -/+1M```

#### 3. find by permission 

```find ./mydir -perm 777```

#### 4. find by X last modified days 

```find ./mydir -mtime X``` 

X is an integer.

#### 5. find stuff of user X 

```find ./mydir -user ulysse31```

#### 6. find empty folders 

```find ./mydir -type d -empty```

#### 7. limit depth to 2 levels 

```find -maxdepth 2 ./mydir -type f -name lola```

### 7 nice tricks

#### 1. quickly search in current user homedir

```find ~ -type f -name "todo"```

#### 2. find files accessed in the last 3 hours

```find ./mydir -amin -180```

#### 3. find all files matching pattern "[0-9]"

```find ./mydir -type f -name "*[0-9]"```

#### 4. find read-only files 

```find ./dir -perm /u=r```

#### 5. apply `ls -lah` on each search result 

```find ./mydir -type f -name "*.json" -exec ls -lah {} \;``` or ```find . -type f -name *.json" | xargs ls -lah```

#### 6. set permissions for all dirs 

```find ./mydir -type d -exec chmod 0755 {} \;``` or ```find ./mydir -type d -print0 | xargs -0 chmod 0755```

#### 7. set permissions for all files 

```find ./mydir -type d -exec chmod 0644 {} \;` or `find ./mydir -type f -print0 | xargs -0 chmod 0644```

## About `find`, `grep`, and more complex commands

There are dozens of combos you might want to try, for example, applying `grep` on each result of the `find` command. While it's totally possible, I like to keep it simple, as, most of the time, I only need speed.

If you need more complexity, you can try combos with `|` (pipe) or use the `-exec` option:

```
find . -type f -iname "*.json" -exec grep -L "Wanna be startin' somethin'" {} \;
```

## Remove the annoying "permission denied"

In this cheat sheet, I often use `./mydir` as haystack, but if you need more global search, you will probably get messages like "permission denied," as there are system binaries and protected resources you're not supposed to read with your user account.

To remove useless lines, you can send the output to `/dev/null` at the end of the command line:

```
COMMAND 2> /dev/null
```

It's also possible to combine `find` and `grep` to achieve the same goal:

```
find / -type d -name secret 2>&1 | grep -v "Permission denied"
```
 
## Wrap up

Use `grep` and `find` to save time and energy.

\0/