AWK Notes

AWK fits naturally after grep and sed. Grep finds matching lines, sed edits streams, and AWK lets you work with columns, conditions, totals, and reports without opening a spreadsheet or writing a full script.

1. What is AWK?

AWK = Pattern scanning and text processing language.

Full Form: Named after creators Aho, Weinberger, and Kernighan (1977, Bell Labs).

One-liner definition:
AWK reads files line-by-line, splits each line into fields, and lets you process/filter/transform data using patterns and actions.


2. Why AWK?

ReasonExplanation
Text processingParse logs, configs, and CSV files quickly
Data extractionPull specific columns without loading into Excel
Quick calculationsSum, average, and count without writing a separate script
One-linersHandle small reporting tasks without opening a larger scripting workflow
Universally availablePre-installed on Linux, macOS, WSL

3. When to Use AWK?


4. Who Needs AWK?

RoleUse Case
SysAdminsParse logs, monitor systems
DevOpsProcess CI/CD outputs, configs
Security AnalystsAnalyze access logs, extract IPs
PentestersRecon data parsing, wordlist manipulation
Data EngineersQuick ETL, data cleaning
DevelopersDebug logs, test output parsing

5. AWK vs Others

ToolBest For
grepFinding/matching patterns
sedFind and replace, line editing
awkColumn-based processing, calculations
cutSimple column extraction (less powerful)
Rule of Thumb

Search -> grep | Replace -> sed | Columns + Math -> awk


6. General Syntax

awk [OPTIONS] 'PATTERN {ACTION}' filename
ComponentMeaning
OPTIONSFlags like -F for delimiter
PATTERNCondition to match (optional)
ACTIONWhat to do with matched lines
filenameInput file

If no PATTERN: Action runs on every line.

If no ACTION: Prints entire matching line.


7. Key Options

OptionMeaningExample
-FField separator-F, for CSV, -F: for /etc/passwd
-vDefine variable-v threshold=50000
-fRead awk script from fileawk -f script. awk data.txt

8. Field Separator Deep Dive

Default separator: Whitespace (space/tab).

# CSV (comma)
awk -F, '{print $1}' file.csv

# TSV (tab)
awk -F'\t' '{print $1}' file. tsv

# Colon (like /etc/passwd)
awk -F:  '{print $1}' /etc/passwd

# Pipe
awk -F'|' '{print $1}' file. psv

# Multiple separators (comma OR semicolon)
awk -F'[,;]' '{print $1}' file.txt

9. Built-in Variables

VariableMeaningExample Value
$0Entire current line101,john,engineering,75000,newyork,active
$1, $2... 1st, 2nd... field$1=101, $2=john
NRNumber of Record (line number)1, 2, 3...
NFNumber of Fields in current line6 (for 6-column CSV)
FSField Separator (input),
OFSOutput Field SeparatorDefault: space
RSRecord SeparatorDefault: newline
ORSOutput Record SeparatorDefault: newline
FILENAMECurrent filenameemp.csv

10. Special Blocks

BEGIN Block

Runs before processing any lines.

awk 'BEGIN {print "Starting..."} {print $0}' file.txt

Use cases: Print headers, initialize variables, set FS.

awk 'BEGIN {FS=","; print "Name,Salary"} NR>1 {print $2,$4}' emp.csv

END Block

Runs after all lines processed.

awk '{sum+=$1} END {print "Total:", sum}' numbers.txt

Use cases: Print totals, averages, summaries.


11. Operators

Comparison

OperatorMeaning
==Equal
!=Not equal
>Greater than
<Less than
>=Greater or equal
<=Less or equal

Logical

OperatorMeaning
&&AND
||OR
!NOT

Regex Match

OperatorMeaning
~Matches pattern
!~Does not match
# Name contains "a"
awk -F, '$2 ~ /a/' emp.csv

# Department NOT marketing
awk -F, '$3 ! ~ /marketing/' emp.csv

12. Associative Arrays

Key-value storage - like Python dictionaries.

# Count per department
awk -F, 'NR>1 {dept[$3]++} END {for(d in dept) print d, dept[d]}' emp.csv

# Sum salary per city
awk -F, 'NR>1 {city[$5]+=$4} END {for(c in city) print c, city[c]}' emp.csv

Syntax:

array[key] = value    # assign
array[key]++          # increment
for(var in array)     # loop through keys

13. Useful Functions

String Functions

FunctionMeaningExample
length(s)String lengthlength($2)
toupper(s)Uppercasetoupper($2)
tolower(s)Lowercasetolower($2)
substr(s,start,len)Substringsubstr($2,1,3) -> first 3 chars
gsub(regex,replace,target)Global substitutegsub(/old/,"new",$0)
sub(regex,replace,target)Substitute first matchsub(/old/,"new",$0)
split(s,array,sep)Split string into arraysplit($0,arr,",")
index(s,target)Find positionindex($2,"oh")

Math Functions

FunctionMeaning
int(x)Integer part
sqrt(x)Square root
sin(x), cos(x)Trigonometry
rand()Random 0-1
srand()Seed random

14. Output Formatting

print (simple)

awk -F, '{print $2, $4}' emp.csv
# Output: john 75000

printf (formatted)

awk -F, '{printf "%-10s %d\n", $2, $4}' emp.csv
# Output: john       75000
FormatMeaning
%sString
%dInteger
%fFloat
%-10sLeft-align, 10 chars wide
%10sRight-align, 10 chars wide
%.2fFloat with 2 decimals
\nNewline
\tTab

15. Sample Data: employees.csv

id,name,department,salary,city,status 101,john,engineering,75000,newyork,active 102,sara,marketing,62000,chicago,active 103,mike,engineering,81000,seattle,inactive 104,emma,hr,55000,boston,active 105,alex,marketing,59000,chicago,inactive 106,lisa,engineering,92000,newyork,active 107,david,finance,67000,seattle,active 108,nina,hr,53000,boston,inactive 109,chris,engineering,78000,newyork,active 110,olivia,marketing,61000,chicago,active 111,james,finance,71000,seattle,inactive 112,sophia,hr,58000,boston,active 113,liam,engineering,88000,newyork,active 114,mia,marketing,64000,chicago,inactive 115,noah,finance,69000,seattle,active 116,ava,hr,52000,boston,active 117,ethan,engineering,95000,newyork,inactive 118,isabella,marketing,60000,chicago,active 119,mason,finance,73000,seattle,active 120,charlotte,hr,56000,boston,inactive 121,logan,engineering,84000,newyork,active 122,amelia,marketing,63000,chicago,active 123,lucas,finance,70000,seattle,inactive 124,harper,hr,54000,boston,active 125,jack,engineering,91000,newyork,active 126,ella,marketing,65000,chicago,inactive 127,benjamin,finance,72000,seattle,active 128,aria,hr,57000,boston,active 129,henry,engineering,87000,newyork,inactive 130,scarlett,marketing,66000,chicago,active 131,sebastian,finance,74000,seattle,active 132,grace,hr,51000,boston,inactive 133,daniel,engineering,93000,newyork,active 134,chloe,marketing,68000,chicago,active 135,matthew,finance,76000,seattle,active

16. Practice Drills - Q&A

Basic Extraction

Q1: Print only the `name` column.
awk -F, '{print $2}' emp.csv
Q2: Print `name` and `salary` columns.
awk -F, '{print $2, $4}' emp.csv
Q3: Print header row only.
awk -F, 'NR==1' emp.csv
Q4: Print all rows except header.
awk -F, 'NR>1' emp.csv
Q5: Print last field of each row.
awk -F, '{print $NF}' emp.csv
Q6: Print second-to-last field.
awk -F, '{print $(NF-1)}' emp.csv

Filtering

Q7: Print employees from engineering department.
awk -F, '$3=="engineering"' emp.csv
Q8: Print names with salary > 70000.
awk -F, 'NR>1 && $4>70000 {print $2}' emp.csv
Q9: Print inactive employees.
awk -F, '$6=="inactive"' emp.csv
Q10: Print employees from chicago OR boston.
awk -F, '$5=="chicago" || $5=="boston"' emp.csv
Q11: Print finance employees with salary > 70000.
awk -F, '$3=="finance" && $4>70000 {print $2}' emp.csv
Q12: Print names containing "a".
awk -F, '$2 ~ /a/ {print $2}' emp.csv
Q13: Print employees NOT in marketing.
awk -F, '$3 ! ~ /marketing/' emp.csv

Formatting Output

Q14: Print name: salary format.
awk -F, 'NR>1 {print $2":"$4}' emp.csv
Q15: Print name (tab) department.
awk -F, 'NR>1 {print $2"\t"$3}' emp.csv
Q16: Print names in uppercase.
awk -F, 'NR>1 {print toupper($2)}' emp.csv
Q17: Print formatted table - name left-aligned 12 chars, salary right-aligned 8 chars.
awk -F, 'NR>1 {printf "%-12s %8d\n", $2, $4}' emp.csv

Counting

Q18: Count total employees (excluding header).
awk -F, 'NR>1 {count++} END {print count}' emp.csv
Q19: Count employees per department.
awk -F, 'NR>1 {dept[$3]++} END {for(d in dept) print d, dept[d]}' emp.csv
Q20: Count employees per city.
awk -F, 'NR>1 {city[$5]++} END {for(c in city) print c, city[c]}' emp.csv
Q21: Count active vs inactive employees.
awk -F, 'NR>1 {status[$6]++} END {for(s in status) print s, status[s]}' emp.csv

Math & Aggregation

Q22: Calculate total salary sum.
awk -F, 'NR>1 {sum+=$4} END {print sum}' emp.csv
Q23: Calculate average salary.
awk -F, 'NR>1 {sum+=$4; count++} END {print sum/count}' emp.csv
Q24: Find highest salary.
awk -F, 'NR>1 && $4>max {max=$4} END {print max}' emp.csv
Q25: Find name of employee with highest salary.
awk -F, 'NR>1 {if($4>max){max=$4; name=$2}} END {print name}' emp.csv
Q26: Find lowest salary.
awk -F, 'NR==2 {min=$4} NR>2 && $4
Q27: Calculate total salary per department.
awk -F, 'NR>1 {dept[$3]+=$4} END {for(d in dept) print d, dept[d]}' emp.csv
Q28: Calculate average salary per city.
awk -F, 'NR>1 {sum[$5]+=$4; count[$5]++} END {for(c in sum) print c, sum[c]/count[c]}' emp.csv

Advanced

Q29: Print employees with salary above average.
awk -F, 'NR>1 {sal[NR]=$4; name[NR]=$2; sum+=$4; count++} END {avg=sum/count; for(i in sal) if(sal[i]>avg) print name[i], sal[i]}' emp.csv
Q30: Print top 3 highest paid employees.
awk -F, 'NR>1 {print $4, $2}' emp.csv | sort -rn | head -3
Q31: Print department with highest total salary.
awk -F, 'NR>1 {dept[$3]+=$4} END {for(d in dept) if(dept[d]>max){max=dept[d]; top=d} print top, max}' emp.csv
Q32: Add row numbers to output.
awk -F, 'NR>1 {print NR-1, $2, $4}' emp.csv
Q33: Print only unique departments.
awk -F, 'NR>1 && ! seen[$3]++ {print $3}' emp.csv
Q34: Print employees and label salary as HIGH (>75000) or LOW.
awk -F, 'NR>1 {print $2, ($4>75000 ? "HIGH" :  "LOW")}' emp.csv
Q35: Swap name and department columns in output.
awk -F, 'NR>1 {print $3, $2}' emp.csv

17. Quick Reference Cheatsheet

TaskCommand
Print column 2awk -F, '{print $2}' file
Print multiple columnsawk -F, '{print $1, $3}' file
Skip headerawk -F, 'NR>1' file
Filter by valueawk -F, '$3=="value"' file
Filter by numberawk -F, '$4>1000' file
Regex matchawk -F, '$2 ~ /pattern/' file
Count rowsawk 'END {print NR}' file
Sum columnawk -F, '{sum+=$4} END {print sum}' file
Averageawk -F, '{sum+=$4} END {print sum/NR}' file
Group countawk -F, '{arr[$3]++} END {for(k in arr) print k, arr[k]}' file
Group sumawk -F, '{arr[$3]+=$4} END {for(k in arr) print k, arr[k]}' file
Find maxawk -F, '$4>max {max=$4} END {print max}' file
Unique valuesawk -F, '! seen[$3]++ {print $3}' file
Format outputawk -F, '{printf "%-10s %d\n", $2, $4}' file

18. Common Mistakes to Avoid

Common fixes
MistakeFix
Forgetting -F, for CSVSpecify the delimiter
Using = instead of === assigns, == compares
Spaces around -F-F, not -F ,
Wrong quotesUse single quotes '...' around awk program
Forgetting $ for fields$3 not 3
Multiple END blocksOnly one END {} allowed

19. Real-World Use Cases

Parse /etc/passwd

# List all usernames
awk -F:  '{print $1}' /etc/passwd

# Find users with bash shell
awk -F: '$7 ~ /bash/ {print $1}' /etc/passwd

Analyze Access Logs

# Count requests per IP
awk '{ip[$1]++} END {for(i in ip) print ip[i], i}' access.log | sort -rn | head -10

# Find 404 errors
awk '$9==404 {print $7}' access.log

Process CSV Reports

# Sum sales column
awk -F, 'NR>1 {sum+=$5} END {print "Total Sales:", sum}' sales.csv

# Find above-average performers
awk -F, 'NR>1 {sum+=$5; count++; data[NR]=$0} END {avg=sum/count; for(i in data) {split(data[i],a,","); if(a[5]>avg) print a[1], a[5]}}' sales.csv

20. Next Steps

  1. Practice the drills until the common patterns feel familiar
  2. Create your own sample files and queries
  3. Combine with grep and sed in pipelines
  4. Apply to real logs on your Kali VM
  5. Move to the sed notes next

AWK notes complete
Continue with grep, sed, and shell pipelines to make the examples more useful.