The colleague's command is built from three moves: cut out a column, sort the lines and count the identical ones.
cut cuts a column out of each line: -d' ' sets the delimiter, a space, and -f1 the column number. cut -d' ' -f1 access.log prints the addresses. In a log line, the page is the seventh word (-f7) and the response code the ninth (-f9).
sort puts lines in alphabetical order. uniq -c glues the repeats of a line together and puts their count in front of it. See how uniq copes without sort.
Count addresses without sort and with it
In ~/pipe-lab, run two commands: counting addresses with uniq -c without sort, and the same count with sort.
First, predict
What will the first command, with no sort before uniq, print?
Now start the exercise, run the command and compare your prediction with the output.
uniq compares each line with the one before it and glues identical lines together only when they stand next to each other. In the log, requests from different addresses are mixed up, and one address turns up many times here and there — uniq counts each run separately. sort puts identical lines side by side, and after it uniq -c counts every address in full. That is why sort nearly always comes before uniq.