golf

command module
v0.0.0-...-e0215d9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 9, 2021 License: MIT Imports: 11 Imported by: 0

README

golf: Go one-liner fun

GoDev

Golf follows the tradition of shell, awk, and perl, letting you write Go programs as one-liners.

Invoke golf with a snippet of Go code in the -e flag, which will be compiled and run for you.

Additional flags such as -n turn on awk/perl-like line mode, which are useful in processing text data. See the examples below and in the godoc.

Some variables and functions are provided in the prelude package. These are inlined and made available to the one-liner. They are common elements of one-liner coding, for example the current line being processed in line mode.

Examples

  # cat -n (see more about "line mode" in command godoc)
  golf -ne 'fmt.Printf("%6d  %s", LineNum, Line)' FILE1 FILE2

  # head MYFILE
  golf -pe 'if LineNum == 10 { break File }' MYFILE

  # Additional packages may be imported using -M pkg. Alternatively,
  # specify the -g flag to let goimports figure it out.
  golf -gle 'Print("The time is ", time.Now())'

  # -a mode (which implies -n) automatically splits input fields.
  # These can be accessed from the Fields slice, or using
  # the convenient Field accessor (supports 1-based and negative indexes).
  ps aux | golf -ale 'Print(Field(5))'
  echo "tom, dick, and harry" | golf -ale 'Print(Field(-2))'

  # Sum sizes. Note flags replacing awk/perl BEGIN and END blocks.
  ls -l | golf -al -BEGIN 'sum := 0' -e 'sum += GAtoi(Field(5))' -END 'Print(sum)'

  # Convert TSV to CSV.
  golf -F '/\t/' -ple 'for i, v := range Fields { Fields[i] = strconv.Quote(v) }; Line = Join(Fields, ",")'

  # Upper-case the contents of files, editing them in-place.
  golf -pI .bak -e 'Line = strings.ToUpper(Line)' FILE1 FILE2

  # -i does the same with no backup.
  # Perl users note: -i does not take arguments; "ne" here mean -n -e.
  find . -name \*.css | xargs golf -ine 'Print(strings.ReplaceAll(Line, "chartreuse", "lime"))'

Install

go install github.com/gaal/golf@latest

License

MIT - See LICENSE file.

Documentation

Overview

Command golf provides some Go one-liner fun.

Invoke it with a snippet of Go code in the -e flag, which will be compiled and run for you.

Additional flags such as -n turn on awk/perl-like line mode, which are useful in processing text data. See the examples and flags sections below.

Some variables and functions are provided in the prelude package. These are inlined and made available to the one-liner. They are common elements of one-liner coding, for example the current line being processed in line mode.

Examples

Try these on your command line.

# Put your oneliner in -e. Here we use the builtin println.
golf -e 'println(9*6)'

# Explicitly import additional packages (don't have to be from the stdlib)
# with the -M flag, which may be repeated.
golf -M fmt -M math -e 'fmt.Println(math.Pi)'

# Some standard library packages are imported automatically.
# goimports can run for you with -g, so -M is often not needed.
golf -e 'fmt.Fprint(os.Stderr, "hi\n")'
golf -gle 'Print("The time is ", time.Now())'

# cat -n (see more about "line mode" below)
golf -n -e 'fmt.Printf("%6d  %s", LineNum, Line)' MYFILE

# Use prelude Die function (takes raw error or fmtstring+args)
golf -l -e 'if data, err := os.ReadFile("MYFILE"); err != nil { Die(err) }; Print(len(data))'

# head MYFILE
golf -p -e 'if LineNum == 10 {break File}' MYFILE

# -a mode (which implies -n) automatically splits input fields.
# These can be accessed from the Fields slice, or using
# the convenient Field accessor (supports 1-based and negative indexes).
ps aux | golf -ale 'Print(Field(5))'

# Prints "and". Could also say "Field(-2)".
echo "tom, dick, and harry" | golf -ape 'Line = Field(3)'

# Input field separation uses strings.Fields by default.
# Supply the -F flag to override (-F implicitly means -a and -n).
# Can also be a regexp; see docs for prelude.GSplit.

# All users on the system.
golf -F : -e 'Print(Field(1))' /etc/passwd

# Convert TSV to CSV.
golf -F '/\t/' -ple 'for i, v := range Fields { Fields[i] = strconv.Quote(v) }; Line = Join(Fields, ",")'

# sum sizes. Note -b and E replace awk/perl BEGIN and END blocks.
ls -l | golf -alb 'sum := 0' -e 'sum += GAtoi(Field(5))' -E 'Print(sum)'

Flags

golf mimics perl's flags, but not perfectly so.

You can cluster one-letter flags, so -lane means the same as -l -a -n -e as it does in perl.

The -b and -E flags act as replacements for awk and Perl's BEGIN and END blocks. They are inserted before and after the -e snippet and only run once each. They are inserted in the same scope as the -e script, so variables declared in BEGIN are available for later blocks. -BEGIN and -END are aliases for -b and -E respectively.

Line mode

-n puts golf in line mode: each command-line argument is treated as a filename, which is opened in succession. Its name will populate the Filename variable. Lines are then scanned, populating the Line variable. Stdin is read instead of a named file if no filenames were provided.

These do the same thing as the cat example above:

cat MYFILE | golf -n -e 'fmt.Printf("%6d  %s", LineNum, Line)'
golf -n -e 'fmt.Printf("%6d  %s", LineNum, Line)' < MYFILE

# Unix cat concatenates multiple files. This does, too.
golf -ne 'Print(Line)' FILE1 FILE2 FILE2

The File and Line labels can be continued/broken from to skip inputs.

-p implies -n and adds a "Print(Line)" call after each line. So you can even say:

golf -pe '' FILE1 FILE2 FILE3

In-place mode

-i causes edits to happen in-place: each input file is opened, unlinked, and the default output (Print, Printf) is sent to a new file with the original's name.

-I does the same, but keeps a backup of the original, according to the same renaming rules that perl -i uses:

  • if the replacement contains no "*", it is used as a literal suffix.
  • otherwise, each occurrence of * is replaced with the original filename.

Like perl, we do not support crossing filesystem boundaries in backups, nor do we create directories.

Unlike perl, in-place backup uses the -I flag, not the -i flag with an argument. Go's standard flag library does not support optional flags. So these don't act the same:

perl -ib FILE1 FILE2  # Runs the perl program in FILE1 with backup to FILE2.
golf -ib WORD FILE    # Runs WORD in BEGIN stage, FILE will end up truncated.

No script mode

golf does not support a script mode (e.g., "golf FILE", or files with #!golf).

If you are writing a Go program in an editor, just go run it. If looking for convenience, see if package Prelude contains anything useful.

Directories

Path Synopsis
Package prelude provides convenient functionality for Go one-liners.
Package prelude provides convenient functionality for Go one-liners.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL