Skip to content
ohsudo, Home
Linux

find, grep, sed and awk Cheat Sheet

Practical recipes for find, grep, sed and awk: find large or old files, search logs, replace text across files, sum columns, and combine them in one-liners

Updated November 6, 2026 · Applies to GNU findutils · GNU grep · GNU sed · GNU awk · Ubuntu · Debian · RHEL / Rocky / AlmaLinux

find: by name and type

Terminal window
find . -name '*.log' # by name (quote the pattern)
find . -iname 'readme*' # ignore case
find /etc -type f -name '*.conf' # files only
find . -type d -name node_modules # folders only
find . -maxdepth 2 -name '*.yml' # not too deep
find . -path ./node_modules -prune -o -name '*.js' -print # skip a folder

find: by size and time

Terminal window
find /var -type f -size +100M # bigger than 100 MB
find / -xdev -type f -size +1G 2>/dev/null # on this disk only
find /var/log -type f -mtime +30 # changed over 30 days ago
find . -type f -mmin -60 # changed in the last hour
find . -type f -empty # empty files
find . -newer reference.txt # newer than a file

find: by owner and permissions

Terminal window
find /srv -user root # owned by root
find /srv ! -user www-data # not owned by www-data
find . -type f -perm 777 # exactly 777
find . -type f -perm -o+w # writable by anyone
find . -type f -perm /111 # executable by someone

The chmod Calculator explains those numbers.

find: act on the results

Terminal window
find . -name '*.tmp' -delete # delete (test without -delete first)
find . -type f -name '*.sh' -exec chmod +x {} + # one command, many files
find . -type f -exec grep -l 'TODO' {} + # files containing a word
find . -type d -exec chmod 755 {} + # folders only
find . -name '*.log' -print0 | xargs -0 gzip # safe with spaces in names
find . -type f -printf '%s %p\n' | sort -n | tail # largest files

For a huge number of files, this avoids Argument list too long.

Terminal window
grep 'error' app.log # lines containing it
grep -i 'error' app.log # ignore case
grep -v 'debug' app.log # lines NOT containing it
grep -n 'error' app.log # with line numbers
grep -c 'error' app.log # how many lines
grep -w 'cat' file # whole word only
grep -F '1.2.3.4' file # plain text, not a pattern

grep: more

Terminal window
grep -r 'listen 80' /etc/nginx/ # in a folder
grep -rl 'old-name' . # only the file names
grep -rn --include='*.py' 'import os' . # only some files
grep -r --exclude-dir=.git 'TODO' . # skip a folder
grep -A3 -B1 'error' app.log # 3 lines after, 1 before
grep -C2 'error' app.log # 2 lines around
grep -E 'error|fatal' app.log # either one (extended regex)
grep -E '^[0-9]{4}-' app.log # lines starting with a year
grep -o 'id=[0-9]*' app.log # only the matching part
grep -P '\d+\.\d+' file # Perl regex, with \d and lookaround

Plain grep doesn’t know \d, + or | the way you may expect, so use -E, or -P for Perl syntax. For matching IP addresses, ports or dates, test your pattern first.

sed: replace

Terminal window
sed 's/old/new/' file # first on each line (prints; file unchanged)
sed 's/old/new/g' file # all on each line
sed -i 's/old/new/g' file # change the file
sed -i.bak 's/old/new/g' file # keep a backup as file.bak
sed 's#/usr/local#/opt#g' file # another delimiter, for paths
sed -E 's/([0-9]+)-([0-9]+)/\2-\1/' file # groups (extended regex)
sed -i 's/\r$//' file # Windows line endings to Linux

On macOS, -i needs an argument: sed -i '' 's/old/new/g' file.

Across many files:

Terminal window
grep -rl 'old-name' src/ | xargs sed -i 's/old-name/new-name/g'
find . -name '*.conf' -exec sed -i 's/8080/9090/g' {} +

sed: lines

Terminal window
sed -n '10,20p' file # print lines 10 to 20
sed '5d' file # delete line 5
sed '/^#/d' file # delete comment lines
sed '/^$/d' file # delete empty lines
sed '/pattern/d' file # delete matching lines
sed -n '/start/,/end/p' file # print between two patterns
sed '1i\# header' file # insert before line 1
sed '$a\last line' file # add after the last line

awk: columns

Terminal window
awk '{print $1}' file # first column
awk '{print $NF}' file # last column
awk '{print $1, $3}' file # two columns
awk -F: '{print $1}' /etc/passwd # another separator
awk -F, '{print $2}' data.csv # simple CSV, with no quoted commas
awk 'NR>1' file # skip the header
awk 'NR==5' file # only line 5
awk 'NF' file # skip empty lines

awk: filter and calculate

Terminal window
awk '$3 > 100' file # where column 3 is over 100
awk '$1 == "GET"' access.log # where column 1 equals GET
awk '/error/ {print $2}' app.log # column 2 of matching lines
awk '{s += $3} END {print s}' file # sum of a column
awk '{s += $3} END {print s/NR}' file # average
awk '{c[$1]++} END {for (k in c) print c[k], k}' file # count by value

Together

Terminal window
# the 10 IP addresses with the most requests
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10
# status codes in an nginx log
awk '{print $9}' access.log | sort | uniq -c | sort -nr
# errors per hour
grep -i error app.log | cut -c1-13 | sort | uniq -c
# the biggest folders here
du -xh --max-depth=1 . | sort -h | tail -n 10
# all listening ports, as numbers
ss -tln | awk 'NR>1 {print $4}' | sed 's/.*://' | sort -un

Practice these

Guided lessons, in your browser: grep, pipes and redirects, sort and uniq, sed and find.