MCPcopy Index your code
hub / github.com/benhoyt/goawk

github.com/benhoyt/goawk @v1.31.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.31.0 ↗ · + Follow
731 symbols 1,968 edges 42 files 278 documented · 38% 2 cross-repo links updated 8d agov1.31.0 · 2025-12-23★ 2,0452 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

GoAWK: an AWK interpreter with CSV support

Documentation GitHub Actions Build

AWK is a fascinating text-processing language, and somehow after reading the delightfully-terse The AWK Programming Language I was inspired to write an interpreter for it in Go. So here it is, feature-complete and tested against "the one true AWK" and GNU AWK test suites.

GoAWK is a POSIX-compatible version of AWK, and additionally has a CSV mode for reading and writing CSV and TSV files. This feature was sponsored by the library of the University of Antwerp. Read the CSV documentation.

You can also read one of the articles I've written about GoAWK:

Basic usage

To use the command-line version, simply use go install to install it, and then run it using goawk (assuming ~/go/bin is in your PATH):

$ go install github.com/benhoyt/goawk@latest

$ goawk 'BEGIN { print "foo", 42 }'
foo 42

$ echo 1 2 3 | goawk '{ print $1 + $3 }'
4

# Or use GoAWK's CSV and @"named-field" support:
$ echo -e 'name,amount\nBob,17.50\nJill,20\n"Boba Fett",100.00' | \
  goawk -i csv -H '{ total += @"amount" } END { print total }'
137.5

To use it in your Go programs, you can call interp.Exec() directly for simple needs:

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
// baz

Or you can use the parser module and then interp.ExecProgram() to control execution, set variables, and so on:

src := "{ print NR, tolower($0) }"
input := "A\naB\nAbC"

prog, err := parser.ParseProgram([]byte(src), nil)
if err != nil {
    fmt.Println(err)
    return
}
config := &interp.Config{
    Stdin: strings.NewReader(input),
    Vars:  []string{"OFS", ":"},
}
_, err = interp.ExecProgram(prog, config)
if err != nil {
    fmt.Println(err)
    return
}
// Output:
// 1:a
// 2:ab
// 3:abc

If you need to repeat execution of the same program on different inputs, you can call interp.New once, and then call the returned object's Execute method as many times as you need.

Read the package documentation for more details.

Differences from AWK

The intention is for GoAWK to conform to awk's behavior and to the POSIX AWK spec, but this section describes some areas where it's different.

Additional features GoAWK has over AWK:

  • It has proper support for CSV and TSV files (read the documentation).
  • It's the only AWK implementation we know with a code coverage feature (read the documentation).
  • It supports negative field indexes to access fields from the right, for example, $-1 refers to the last field.
  • It's embeddable in your Go programs! You can even call custom Go functions from your AWK scripts.
  • Most AWK scripts are faster than awk and on a par with gawk, though usually slower than mawk. (See recent benchmarks.)
  • The parser supports 'single-quoted strings' in addition to "double-quoted strings", primarily to make Windows one-liners easier when using the cmd.exe shell (which uses " as the quote character).

Things AWK has over GoAWK:

  • Scripts that use regular expressions are slower than other implementations (unfortunately Go's regexp package is relatively slow).
  • AWK is written by Alfred Aho, Peter Weinberger, and Brian Kernighan.

Stability

This project has a good suite of tests, which include my own intepreter tests, the original AWK test suite, and the relevant tests from the Gawk test suite. I've used it a bunch personally, and it's used in the Benthos stream processor as well as by the software team at the library of the University of Antwerp. However, to err == human, so please use GoAWK at your own risk. I intend not to change the Go API in a breaking way in any v1.x.y version.

AWKGo

The GoAWK repository also includes the creatively-named AWKGo, an AWK-to-Go compiler. This is experimental and is not subject to the stability requirements of GoAWK itself. You can read more about AWKGo or browse the code on the awkgo branch.

License

GoAWK is licensed under an open source MIT license.

The end

Have fun, and please contact me if you're using GoAWK or have any feedback!

Extension points exported contracts — how you extend this code

Node (Interface)
Node is an interface to be satisfied by all AST elements. We need it to be able to work with AST in a generic way, like [38 …
internal/ast/ast.go
Expr (Interface)
Expr is the abstract syntax tree for any AWK expression. [19 implementers]
internal/ast/ast.go
Stmt (Interface)
Stmt is the abstract syntax tree for any AWK statement. [16 implementers]
internal/ast/ast.go
Visitor (Interface)
Visitor has a Visit method which is invoked for each node encountered by Walk. If the result visitor w is not nil, Walk [3 …
internal/ast/walk.go

Core symbols most depended-on inside this repo

add
called by 120
internal/compiler/compiler.go
fetch
called by 90
internal/compiler/disassembler.go
toString
called by 89
interp/interp.go
String
called by 78
internal/ast/ast.go
num
called by 70
interp/value.go
num
called by 64
interp/value.go
writeOpf
called by 63
internal/compiler/disassembler.go
next
called by 62
parser/parser.go

Shape

Method 382
Function 235
Struct 95
TypeAlias 11
Interface 8

Languages

Go100%
Python1%

Modules by API surface

internal/ast/ast.go200 symbols
interp/interp_test.go79 symbols
parser/parser.go59 symbols
interp/interp.go38 symbols
internal/compiler/compiler.go36 symbols
interp/io.go35 symbols
goawk_test.go29 symbols
interp/iostream.go28 symbols
internal/resolver/resolve.go22 symbols
interp/value.go20 symbols
lexer/lexer_test.go18 symbols
lexer/lexer.go18 symbols

Used by 2 indexed graphs manifest dependencies, hub-wide

For agents

$ claude mcp add goawk \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page