Linux Basic — Regular Expressions Practice
Practice Exercises — Regular Expressions
Work through these using only grep, sed, awk, and Bash =~. Use -E (or ERE-native tools) throughout.
Warm-up — grep -E
- Find errors. From
app.log, print every line starting withERRORorFATAL. - Quiet test. Write an
ifthat usesgrep -Eqto detect whetherapp.logcontains anypanic. - Extract IPs. Print every IPv4-looking token from
access.log, deduplicated and sorted. - Email extraction. Pull every email address from a free-form text file. Case-insensitive.
- Count by category. Count how many lines start with
INFO,WARN,ERRORand print as a 3-line summary.
Bash =~ Operator
- Validate a port number. Read a port from
read -p; accept only digits, then check the range 1–65535. - Parse a tag. Given
tag="release-v2.4.1-rc3", extractmajor,minor,patchinto named variables usingBASH_REMATCH. - Detect file type by name. Given a filename, branch into
image,archive,script, orotherusing one[[ $f =~ ... ]]per branch. - The quoting trap. Show that
[[ "$x" =~ "^[0-9]+$" ]]matches only the literal string; then fix it. - Email validator. Write a
is_email()function returning 0/1 using a single[[ =~ ]]with a reasonable pattern.
POSIX Character Classes
- Identifier check. Use
[[:alpha:]_][[:alnum:]_]*to validate identifiers (letgrep -Eqor Bash=~decide). - Hex colour. Validate a string is
#followed by exactly 6 hex digits ([[:xdigit:]]). - Trim whitespace. Use
sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//'on a file with mixed leading/trailing spaces. - Locale impact. With
LC_ALL=en_US.UTF-8, show thatgrep -Eo '[[:alpha:]]+' <<< "café"returnscafé; then withLC_ALL=Cshow it stops atcaf.
sed
- Swap key=value. Convert
name=AliceintoAlice=nameusing a singlesed -Ewith capture groups. - Path rewrite. Replace
/old/pathwith/new/pathin a config — pick a non-/delimiter. - Delete blanks and comments. From an ini file, delete blank lines and lines beginning with
;or#. - Section-scoped edit. In
app.ini, changehost=...tohost=db.prodonly inside the[database]section. - Portable in-place. Implement a portable
sed_inplace()function that works on both GNU and BSDsedusingmktemp+mv.
awk
- Filter by field. From
/etc/passwd, list usernames whose shell ends inbash. - Sum a column. Given a CSV with
name,amountrows, sumamountand print atEND. - Group-by count. From
access.log, count requests per HTTP status code (assume status is field 9). Sort descending. - Replace inside one field. In a tab-separated file, lowercase only column 3 and reprint the whole row.
- Dedupe adjacent. Remove consecutive duplicate lines without using
uniq. - CSV with embedded commas. Mention which assumption breaks plain
-F,parsing, and pick the right tool (csvkit,mlr) for real CSV.
Stretch
- Build a small linter. Scan a directory of
.shfiles; print every line that uses unquoted$var(heuristic:grep -En '[^"]\$[A-Za-z_]'). Accept that this is a heuristic. - Mask secrets in a log. Replace anything that looks like an API key (
[A-Za-z0-9]{32,}) with***REDACTED***usingsed -E. - Two-pass
awk. First pass: collect set of valid IDs fromvalid.txt. Second pass: print onlyevents.csvrows whose ID is in the set. Useawk 'NR==FNR{...; next} {...}' valid.txt events.csv. - Date range filter. From a log with
YYYY-MM-DDat the start of each line, print only lines between two dates usingawkand string comparison. - Generate
mvcommands. Usels | sed -E 's/(.*)\.txt$/mv & \1.md/'to rename.txtto.md— pipe throughshonce you’ve verified.
Verification Checklist
- Every pattern with
( ) + ? |uses-E(orawk/ Bash=~) [[:digit:]]etc. are inside two sets of brackets- All
sedsubstitutions you’d run on real files are tested without-ifirst - All
awkfield accesses use the right-Fseparator - No regex is unanchored when validating input
Next chapter → Interactive Scripts