Skip to content

Instantly share code, notes, and snippets.

@rlonstein
Last active June 13, 2017 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rlonstein/90d53fdeea31d2137737 to your computer and use it in GitHub Desktop.
Save rlonstein/90d53fdeea31d2137737 to your computer and use it in GitHub Desktop.
TXR example for parsing dhcpd.leases(5) and look up in IEEE OUI data
#!/usr/bin/env txr -f
@(block)
@(next "/usr/share/ieee-data/oui.txt")
@(do (defvar OUICORP (hash :equal-based)))
@(repeat)
@{OUI /([a-fA-F0-9][a-fA-F0-9][\-])*([a-fA-F0-9][a-fA-F0-9])/} (hex)@/[\t ]+/@CORP
@(do(sethash OUICORP OUI CORP))
@(end)
@(end)
@(do (defvar STATE))
@(collect)
lease @{IPADDR /\d+\.\d+\.\d+\.\d+/} {@\
@(gather)
@/\s/client-hostname "@HOSTNAME";
@/\s/hardware ethernet @{MAC /([a-fA-F0-9][a-fA-F0-9][:])*([a-fA-F0-9][a-fA-F0-9])/};
@/\s/starts @/[0-6]/ @START;
@/\s/ends @/[0-6]/ @END;
@(maybe)
@/\s/binding state @STATE;
@(end)
@(end)
}
@(end)
@(output)
IPAddr|Hostname|HWAddr|OUI|Start|End|State
@(repeat)
@IPADDR|@HOSTNAME|@MAC|@\
@(gethash OUICORP (upcase-str (regsub #/:/ "-" (sub-str [MAC 0 8]))) "unknown")|@\
@START|@END|@STATE
@(end)
@(end)
Copy link

ghost commented Jun 13, 2017

The #!/usr/bin/env txr -f trick won't work on operating systems which allow only a single argument in the hash bang line. Like, oh, Linux. Basically, env is invoked with txr -f as its argv[1].

As of TXR 177, the interpreter supports an (as far as I know) novel trick which has been christened "the hash bang null hack".

In a nutshell, what you can do is this: #!/usr/bin/env txr<NUL>other args here<NL>. That is to say, you put a null byte after the argument to the env interpreter. txr will automatically find this null byte, and look for more arguments after that byte, up to the terminating newline.

It has been tested to work Linux, MacOS, Cygwin and Solaris 10. These systems are fooled; either their kernels don't pass the stuff after the null to env at all, or else env ignores it since argv[1], being a null-terminated C string, effectively ends at the null byte even if the other bytes do follow. Either way, env nicely finds txr. Then txr opens the script, reads the line from its own stream, and processes the stuff after the null.

The documentation is here: http://www.nongnu.org/txr/txr-manpage.html#N-01DF6FA2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment