Comment

Comment by sgarland

Every time I see things like this, I feel like the person must be unaware of awk.

  # the original one-liner to get unique IP addresses
  cut -d' ' -f 1 access.log | sort | uniq -c | sort -rn | head
  # turns into this with GNU awk
  gawk '{PROCINFO["sorted_in"] = "@val_num_desc"; a[$1]++} END {c=0; for (i in a) if (c++ < 10) print a[i], i}' access.log
It's also far, far faster on larger files (base-spec M1 Air):

   $ wc -lc fake_log.txt
   1000000 218433264 fake_log.txt

  $ hyperfine "gawk '{PROCINFO[\"sorted_in\"] = \"@val_num_desc\"; a[\$1]++} END {c=0; for (i in a) if (c++ <10) print a[i], i}' fake_log.txt"
  Benchmark 1: gawk '{PROCINFO["sorted_in"] = "@val_num_desc"; a[$1]++} END {c=0; for (i in a) if (c++ <10) print a[i], i}' fake_log.txt
  Time (mean ± σ):      1.250 s ±  0.003 s    [User: 1.185 s, System: 0.061 s]
  Range (min … max):    1.246 s …  1.254 s    10 runs

  $ hyperfine "cut -d' ' -f1 fake_log.txt | sort | uniq -c | sort -rn | head"
  Benchmark 1: cut -d' ' -f1 fake_log.txt | sort | uniq -c | sort -rn | head
  Time (mean ± σ):      4.844 s ±  0.020 s    [User: 5.367 s, System: 0.087 s]
  Range (min … max):    4.817 s …  4.873 s    10 runs
Interestingly, GNU cut is significantly faster than BSD cut on the M1:

  $ hyperfine "gcut -d' ' -f1 fake_log.txt | sort | uniq -c | sort -rn | head"
  Benchmark 1: gcut -d' ' -f1 fake_log.txt | sort | uniq -c | sort -rn | head
  Time (mean ± σ):      3.622 s ±  0.004 s    [User: 4.149 s, System: 0.078 s]
  Range (min … max):    3.616 s …  3.629 s    10 runs
parent sgarland 3 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton