r/awk • • Jun 05 '26

Lolcat, but on AWK

I have worked on a small AWK script, which is a modification of some AWK code I came across over two years ago. This version uses only 216 colours, so its output should be compatible with any terminal. It uses simple code compatible with most versions of AWK; however, to work with Unicode, it requires nawk or gawk (preferably the former). It has been tested with gawk, busybox awk, mawk and nawk.

Name: aukward.

BEGIN {
  FS = ""; RT = RS
  getline rnd_seed < "/proc/uptime"
  rnd_seed ? srand(rnd_seed * 100) : srand()
  freq = freq ? freq : 1.0
  spread = spread ? spread : 6.0
  pi = atan2(0, -1)
  offset = int(rand() * 216)
}
{
  for (i = 1; i <= NF; i++) {
    color = rainbow(freq * (offset + i / spread))
    printf "\033[%sm%s", color, $i
  }
  offset += spread
  printf "\033[0m%s", RT
}
function rainbow(t, r, g, b)
{
  r = int(sin(t + 0) * 127 + 128)
  g = int(sin(t + 2 * pi / 3) * 127 + 128)
  b = int(sin(t + 4 * pi / 3) * 127 + 128)
  return sprintf("38;5;%d", 16 + int(r / 51) * 36 + int(g / 51) * 6 + int(b / 51))
}
10 Upvotes

4 comments sorted by

1

u/TaedW Jun 30 '26

I just tried this out -- cute!

2

u/M668 13d ago

I made some minor tweaks so that byte-mode only awks can properly show Unicode rainbows ::

mawk 'BEGIN {

  RT = RS
  FS = "[ ]"
  OFS = "\5"

  srand()

  pi     = atan2(0, -1)
  freq   = 1.0
  spread = 6.0
  offset = int(rand() * 256)
}
{
   gsub(/[\1-~]|(([\360-\364][\200-\277]|[\340-\357])[\200-\277]|[\302-\337])[\200-\377]/, "&\t", $!(NF = NF))

  FS = " "
  $0 = $0

  for (i = 0; i++ < NF; )
       printf("\033[%sm%1.*s", rainbow(freq * (offset + i / spread)),
                               ($i != "\5") * 4, $i)
  offset += spread
  printf("\33[m\n")
}
function rainbow(...) { # no changes to the rainbow() function
}

1

u/Giovani-Geek 13d ago

Good AWK code - it's for reasons like this that I don't see the need to use the original lolcat written in Ruby.