GoAWK: a POSIX AWK interpreter in Go with CSV mode and an embedding API
A POSIX-compliant AWK interpreter written in Go, with CSV support
At a glance
- What is it?
- GoAWK is a Go implementation of AWK that covers the POSIX specification and adds CSV and TSV support with named-field access. It ships as a CLI binary and as a Go library with an API stability guarantee across all v1.x.y releases.
- Who is it for?
- GoAWK suits Go developers who want AWK as an embeddable library and shell scripters who need correct CSV parsing without a preprocessing step. Named-field access via @"fieldname" and the three-level embedding API are the features standard AWK tools do not offer.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Star history
- benhoyt/goawk2,065 ★ · +0
| Repository | 2026-10-11 | 2026-10-23 |
|---|---|---|
| benhoyt/goawk | 2.1k | 2.1k |
0 Stars in the last 12 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
POSIX conformance tested against two AWK test suites
GoAWK sets out to conform to the POSIX AWK specification and to match the behavior of the original awk implementation. It passes both the original 'one true AWK' test suite and the GNU AWK test suite, the two reference points for AWK compatibility, and documents each place where it departs from that specification.
Extensions beyond standard AWK include proper CSV and TSV support with named-field access, negative field indexes such as $-1 to reference the last field, single-quoted strings for easier use in Windows cmd.exe, a code coverage feature, and the ability to call custom Go functions directly from AWK scripts. Each extension is documented separately in the repository, with docs/csv.md and docs/cover.md covering the two largest additions.
Redpanda Connect, the stream processor formerly known as Benthos, uses GoAWK internally. The software team at the library of the University of Antwerp is a listed production user. The author also notes using it personally. Beyond those three mentions, no further deployment details are given, but they place GoAWK outside purely personal projects and confirm it has been running in real workloads.
go install and the Go 1.20 floor, or a prebuilt binary
GoAWK is distributed two ways. Prebuilt binaries for each platform are on the GitHub releases page, which is the route for anyone without a Go toolchain. For Go users, one command installs from source:
go install github.com/benhoyt/goawk@latestGo 1.20 is the minimum, set in go.mod. After install, the binary is available as goawk once ~/go/bin is in PATH. A basic confirmation:
goawk 'BEGIN { print "foo", 42 }'That prints foo 42. Piped input works in the same way as standard awk: passing echo 1 2 3 through the expression { print $1 + $3 } prints 4.
The current release is v1.32.0, published on 2026-09-15, which added support for dynamic RS regex and introduced the Config.FileSystem field to the embedding API. v1.31.0 on 2025-12-23 set the Go 1.20 minimum explicitly. Any environment on an older Go version must upgrade before installing v1.31.0 or later.
The CSV mode uses -i csv, -H and @"fieldname" access
Standard AWK splits input on a field separator. That approach breaks on CSV data when commas appear inside quoted strings, since the parser treats the surrounding quotes as ordinary characters and the inner comma as a field boundary. GoAWK's CSV mode handles RFC-style quoting correctly. Passing -i csv at the command line switches the input parser, and -H designates the first row as a header.
With -H active, named-field access is available through the @"fieldname" syntax. The following command sums the amount column across three rows and a quoted name:
echo -e 'name,amount\nBob,17.50\nJill,20\n"Boba Fett",100.00' | \
goawk -i csv -H '{ total += @"amount" } END { print total }'That prints 137.5. Without -H, the same script would need to know that amount is in column 2, breaking if the column order changed. Named-field access decouples the script from column position entirely.
TSV support uses the same mechanism. Full details are in docs/csv.md at the repository root. Standard awk and gawk have since added basic CSV support with the --csv option. GoAWK describes its own CSV mode as proper support, covering RFC-style quoting and named-field access that those basic implementations do not offer.
Three Go entry points in the embedding API, stable across v1.x.y
GoAWK ships as a Go package at github.com/benhoyt/goawk, making it embeddable in any Go program. Three entry points serve different levels of control over execution.
interp.Exec is the simplest path. It accepts a program string, a field separator, an input reader and an output writer, and compiles and runs the program in one call. An example illustrating the basic flow:
input := strings.NewReader("foo bar\n\nbaz buz")
err := interp.Exec("$0 { print $1 }", " ", input, nil)
if err != nil {
fmt.Println(err)
return
}
// Output:
// foo
// bazThat program prints the first field of each non-empty line. parser.ParseProgram combined with interp.ExecProgram separates compilation from execution. interp.Config carries per-execution settings, including Vars: []string{"OFS", ":"} to set the output field separator from Go code rather than from an AWK variable assignment. For running the same compiled program on many different inputs, interp.New creates a reusable interpreter and its Execute method avoids reparsing on each call.
The Go API is stable across all v1.x.y releases, with no breaking changes intended in that range. A break would require a new major version, which the repository does not mention.
The bytecode VM beats awk for most scripts, but Go's regexp package is the exception
GoAWK started as a tree-walking interpreter and was later converted to a bytecode compiler and virtual machine. The author published an article on that change at benhoyt.com/writings/goawk-compiler-vm/. Most AWK scripts in GoAWK run faster than awk and on a par with gawk, though usually slower than mawk. The benchmark data behind those claims is at benhoyt.com/writings/goawk-compiler-vm/#virtual-machine-results.
The exception is scripts that use regular expressions. Go's regexp package uses a different engine than those in awk, gawk and mawk, and it is relatively slow by comparison. Scripts where most of the work is regex matching over large inputs will run slower than mawk, and that difference is worth measuring before adopting GoAWK for a regex-heavy workload.
Regex performance is the first item in the list of areas where AWK has the advantage over GoAWK, and the gap comes from Go's standard library rather than from GoAWK's design choices. For scripts that do field splitting, arithmetic and string manipulation without heavy regex, the bytecode VM keeps GoAWK competitive with both awk and gawk. The original article at benhoyt.com/writings/goawk/ describes how the tree-walking interpreter was built and what shaped the project's design before the bytecode conversion took place.
Code coverage tracks line execution, and AWKGo is an experimental compiler on a separate branch
Two features sit alongside the main interpreter but are not part of its v1.x.y stability contract.
The code coverage feature records which lines of an AWK script execute during a run; Volodymyr Gubarkov contributed it, with documentation in docs/cover.md at the repository root. Coverage output format and test workflow integration details are not covered in the overview; docs/cover.md is the starting point for anyone who wants to instrument AWK scripts and track which paths execute during a test run.
AWKGo is an AWK-to-Go compiler in the same repository, living on the awkgo branch under a directory named awkgo. It translates AWK programs into Go source code. Unlike the main interpreter, AWKGo carries no backward-compatibility guarantee, and its translation behavior may change across versions without notice. The author published an article on AWKGo at benhoyt.com/writings/awkgo/ for anyone who wants to understand the compiler's design and scope before deciding whether to use it.
Three releases across ten months, MIT licence with no copyleft
v1.32.0 shipped on 2026-09-15 with two additions: support for dynamic RS regex and a new Config.FileSystem field in the embedding API. v1.31.0 on 2025-12-23 raised the minimum Go requirement to 1.20 and made minor fixes. v1.30.1 on 2025-11-16 fixed a specific bug with an empty action block {}. That record, two feature releases and a patch release in ten months, shows steady maintenance. Each release is tagged and the notes describe the changes directly, which makes auditing a version upgrade straightforward.
GoAWK's licence is MIT, with the text in LICENSE.txt at the repository root. MIT requires attribution in distributions and imposes no copyleft obligations. GoAWK can therefore be embedded in proprietary Go programs and shipped in commercial products without triggering source-sharing requirements. Confirm the specific terms in LICENSE.txt directly before redistributing a modified build, since this paragraph is an observation and not legal advice. The go.mod module path is github.com/benhoyt/goawk, and the Go package documentation is at pkg.go.dev/github.com/benhoyt/goawk.
Editorial conclusion
GoAWK suits Go developers who want AWK as an embeddable library and shell scripters who need correct CSV parsing without a preprocessing step. Named-field access via @"fieldname" and the three-level embedding API are the features standard AWK tools do not offer. Skip it when regex performance is the deciding factor: Go's regexp engine is slower than mawk on regex-heavy workloads. Before adopting it as a library, confirm your Go version meets the 1.20 floor and check Config.FileSystem, added in v1.32.0, against your use case at pkg.go.dev/github.com/benhoyt/goawk.
Frequently asked questions
What is GoAWK?
GoAWK is a POSIX-compliant AWK interpreter written in Go. It runs as a standalone command-line tool or as a library embedded in Go programs, and adds CSV and TSV support with named-field access that standard AWK implementations do not include.
How do I install GoAWK?
Two routes are available: download a prebuilt binary from the GitHub releases page, or run go install github.com/benhoyt/goawk@latest with Go 1.20 or later. After the source install, the binary is available as goawk once ~/go/bin is in PATH.
Does GoAWK support CSV files?
Yes. Passing -i csv to the goawk command switches input parsing to RFC-style CSV handling. Adding -H treats the first row as a header and enables @"fieldname" syntax to access columns by name rather than by position. Full documentation is in docs/csv.md.
Can GoAWK be embedded in a Go program?
Yes. The package at github.com/benhoyt/goawk exposes interp.Exec for simple use, interp.ExecProgram with interp.Config for control over variables and execution settings, and interp.New with an Execute method for repeated runs on different inputs. The API will not change in a breaking way across v1.x.y releases.
Is GoAWK faster than gawk?
Most AWK scripts run on a par with gawk. Scripts that rely on regular expressions are an exception, because Go's regexp package is slower than the regex engines other AWK implementations use. For regex-heavy workloads, mawk is the faster alternative.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/benhoyt-goawk)Star history chart for your README
[](https://hysenlabs.com/projects/benhoyt-goawk)Was this useful?