Pipes: how small commands become big ones
A pipe (|) hands one command's output to the next, so grep, awk, sort, uniq -c and wc -l stack into a single question about a log file.
Every command here does exactly one small job, and none of them can answer your question alone. Your app logged 80 lines last night and something is failing. Which URL is failing most? No single command knows. Stack a few and the answer falls out.
What you just learned
A pipe (|) takes what one command printed and hands it to the next one as if you had typed it yourself. That is the whole idea. grep throws away lines, awk throws away columns, sort puts identical things next to each other, uniq -c counts runs of identical lines, and wc -l counts whatever is left.
That is also why uniq needs sort in front of it. uniq only collapses lines that are already next to each other, so without sorting first you get the same URL counted four separate times. It is the most common bug in a beginner pipe, and you just watched it happen instead of being warned about it.
None of these tools know anything about logs, URLs, or your app. They move lines of text around. That is why the same five commands work on log files, CSV exports, lists of filenames, and the output of any other command you will ever meet.
Seen on a real server
3 /api/users- What uniq -c prints: the count padded to seven columns, then the line. sort -rn on top of it puts the biggest number first.
Every command you just ran, you ran as somebody. Next: who that somebody is, and why one account on the box plays by different rules.