grep1-4 Exercise 2: A Small Report from app.log ================================================ (Run from an empty folder. The first block makes the two practice files from the chapter; your own files can skip it.) cat > app.log <<'EOF' 09:00:01 INFO service starting 09:00:02 INFO loading config 09:00:03 WARN config key 'timeout' missing, using default 09:00:04 INFO connecting to database 09:00:09 ERROR database connection refused 09:00:10 INFO retrying in 5s 09:00:15 ERROR database connection refused 09:00:16 ERROR giving up after 2 attempts 09:00:17 INFO switching to read-only mode 09:00:20 INFO listening on port 8080 09:05:00 INFO health check ok 09:10:00 WARN slow response: 2300 ms 09:10:30 INFO health check ok 09:15:00 ERROR disk usage 95%, ERROR threshold 90% 09:15:01 INFO alert sent 09:20:00 INFO health check ok EOF cat > access.log <<'EOF' 10.0.0.5 GET /index.html 200 10.0.0.7 GET /about.html 200 10.0.0.5 POST /login 302 10.0.0.9 GET /missing 404 10.0.0.5 GET /index.html 200 10.0.0.7 GET /index.html 200 10.0.0.5 GET /dashboard 200 10.0.0.9 GET /missing 404 10.0.0.7 GET /logout 302 EOF # --- the exercise --- echo "lines with ERROR: $(grep -c ERROR app.log)" echo "ERROR matches: $(grep -o ERROR app.log | wc -l)" echo "lines without ERROR: $(grep -vc ERROR app.log)" echo "lines in total: $(grep -c '' app.log)" echo echo "by level, biggest first:" grep -oE 'INFO|WARN|ERROR' app.log | sort | uniq -c | sort -rn Output: lines with ERROR: 4 ERROR matches: 5 lines without ERROR: 12 lines in total: 16 by level, biggest first: 10 INFO 5 ERROR 2 WARN WHY THIS WORKS AS AN ANSWER --------------------------- -c counts lines (4), while -o | wc -l counts matches (5): the difference is line 14. -vc counts the lines that do not match, 12, and 4 + 12 = 16, which equals the total from the empty pattern. The last block is the chapter's counting recipe: -o extracts each level, sort puts equal ones together, uniq -c counts each run, sort -rn puts the biggest number first. Without the first sort, uniq would count runs of equal NEIGHBOURS, and the answers would be wrong without any error.