5 min to read
Intrusive Thoughts - AWK for 30 minutes
How to use time functions in AWK

A colleague of mine today posted something unusual in chat - awk for 30 minutes
. On inspection, this almost certainly wasn’t referring to AWK - my favorite data-driven scripting language for UNIX and Linux. After all - firstly this was written by someone who works primarily in a Windows environment, and secondly… how would you even do that? While I’m certain they meant AFK, the question would not go away and I just had to know.
Luckily for my novelty seeking brain, answering this question was not only possible but also quite doable.
Table of Contents
Time functions in AWK
First off, how do we measure time in AWK?
As I discovered on linuxcommands.site, AWK has three functions built in to handle time:
- systime which returns the number of seconds since the epoch which starts at the 1st of January 1970,
- strftime which formats and converts the timestamp to a nice human-readable string, and
- mktime which takes a time string in the format
yyyy mm dd hh mm ss
and converts it to a UNIX timestamp.
Of the three, we can get away with simply using systime as all we’re after is an integer which increments for every second that passes.
Worth noting - these functions may not be available in all versions of AWK. I tested this on GAWK, which definitely does have them.
Writing the script
Next we need to figure out how to measure how many seconds have passed. The easiest way to do that, given that systime will always output the number of seconds since the epoch, is to get the current time when our script starts, and then compare against it until we’ve elapsed 30 minutes. We can use the BEGIN block in AWK to accomplish that like so:
BEGIN{bt = systime()}
Normally with a full-blown AWK script I’d want to write out variable names in full so they’re nice and readable for anyone who comes along to pull apart and modify the script later, but a secondary requirement I was keen to add was turning this into a dirty one-liner that I could use as a reply, so we’re being minimalistic where it’s reasonable to do so. This means bt for begin time for now.
Next up we want to make sure that our AWK script runs until the whole 30 minutes have elapsed. This calls for the use of a loop - specifically a while loop. While loops are a common piece of code in most languages that runs until a certain condition is met. They’re constructed in AWK in a familiar format to anyone cutting code in C-like languages with the syntax while(condition) {perform actions}
. The condition in our case is simple - while the number of seconds elapsed is less than 30 minutes (1800 seconds), continue the loop. We don’t actually have to put any actions in our loop, but to give a nice visual representation of what’s going on under the hood, I’ve also popped a very noisy print statement in which reports the number of seconds elapsed since we started, but you can leave this out if you prefer a quieter output.
{while((systime() - bt) < 1800) {print "seconds elapsed: " (systime() - bt)}}
Once we’ve finished the loop, we finally want to report that our wait is over. To do this, we simply print ‘done’ inside the END block which will run at the very end of our awk script. It looks like this:
END{print "done!"}
Now we can tie all this together into a one-liner we can paste in the terminal. If we wrap the script in single quotes and simply throw it to AWK, a strange thing happens - the script starts but nothing happens and it will behave oddly, appearing to hang. You can send a ctrl+c break signal to AWK to stop it and return to the shell.
This occurs because AWK is expecting to operate on some kind of file input. If you don’t specify a file for AWK to operate on, it assumes you’re going to feed it data line by line in interactive mode. Instead, we want it to just run the timer we set up. To accomplish this, instead of handing it an actual file, we redirect an empty string with a herestring (as explained on Wikipedia’s article on here documents) so that AWK thinks we’ve given it a file to work on. This results in the final script below:
awk 'BEGIN{bt = systime()} {while((systime() - bt) < 1800) {print "seconds elapsed: " (systime() - bt)}} END{print "done!"}' <<< ''
Final thoughts
While this specific example is a silly response to a chatroom message, there are several practical uses of systime in AWK. Some of these might include internally timing your AWK code (without using the external time command available on most Linux distros), printing the time a report generated by AWK was run, or as a function for tracking the delta between last recorded and current time to output dots to screen during a process to show it’s still running.