IME this one-liner can churn through 100MB of log lines in a second. Other solutions like powershell's "select-object -unique" totally choke on the file.
https://www.gnu.org/software/gawk/manual/html_node/Array-Int...
I suspect that it's designed so that hash collisions are impossible until you get to an unrealistic number of characters per line.
I'm not claiming that it will silently break! I'd be very interested in exploring the internals a little more and finding out how hard it is to get a collision in various implementations and how they behave subsequently.
EDIT: I've read chasil's comment and agree that it must be storing raw keys in the array. I guess awk uses separate chaining or something to get around hash collisions.
awk '{a[$0]++}; END{for(b in a) print b, a[b]}'
...will print every unique line in a file with the count. Obviously, that could not be done if the array index was a hash - the array index is the entire line, and the array value is the count.
The original program moves the maintenance of the array into the implicit conditional "pattern," and only prints when the array entry does not yet exist.
These are only used when the allowed memory buffer is exhausted.
You might be better off switching to another scripting language that has some database API for storing key/value pairs on disk.
Or: use a 64 bit machine for a bigger address space, and add temporary swap files so you have more virtual memory.
There are people who are still on 32-bit hardware for serious work?
(Even if I was still on that, I'd probably just fire up a RV64 virtual machine (with swap space added within the VM, of course) simply to access the convenience of a larger address space when needed.)
These also have awk, almost always via Busybox, though using OpenWRT other versions are installable.
BusyBox v1.28.4 () built-in shell (ash)
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
OpenWrt 18.06.2, r7676-cddd7b4c77
-----------------------------------------------------
root@modem:~# uname -a
Linux modem 4.9.152 #0 SMP Wed Jan 30 12:21:02 2019 mips GNU/Linux
root@modem:~# free
total used free shared buffers cached
Mem: 59136 38484 20652 1312 2520 13096
-/+ buffers/cache: 22868 36268
Swap: 0 0 0
root@modem:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 2560 2560 0 100% /rom
tmpfs 29568 1268 28300 4% /tmp
tmpfs 29568 44 29524 0% /tmp/root
tmpfs 512 0 512 0% /dev
/dev/mtdblock5 3520 1772 1748 50% /overlay
overlayfs:/overlay 3520 1772 1748 50% /
root@modem:~# which awk
/usr/bin/awk
root@modem:~# ls -l `which awk`
lrwxrwxrwx 1 root root 17 Jan 30 12:21 /usr/bin/awk -> ../../bin/busybox
root@modem:~# opkg list | grep awk
gawk - 4.2.0-2 - GNU awk
root@modem:~#
... though in this case, adblock runs on a larger and more capable Turris Omnia (8 GB flash, 2 GB RAM). The hourly sort still shows up on system load average plots.Will the BusyBox version of sort use files when there isn't enough RAM, will you have a big enough read/write flash partition for that?
The flexibility of keeping the adblock processing self-contained, rather than processing this on another box and rigging an update mechanism, is appealing.
The 'huge" file is 6MB. That's not immense, but it taxes (overly constrained, IMO) typical SOH router resources.
The flexibility afforded, for pennies to a few dollars, of, say, > 1 GB storage and 500 MB RAM, is tremendous.
I'm not sure what Busybox's sort does, though on an earlier iteration on a mid-oughts Linksys WRT54g router running dd-wrt, sorting was infeasible. I hadn't tried the awk trick.
It did have a Busybox awk though, which proved useful.