rkg
record + knit + grid
About
rkg is the short crate/bin name for a one-liner oriented record/grid processor.
This version implements the current function-level DSL with:
r./rec.for record moded./grid.for grid mode- method chaining with
. - statement reset with
; - AWK-like separators:
fs,rs,ofs,ors -F/--field-separatorfor AWK-like initial field separator override
Build
|
DSL shape
r.fs(",").x(2,";").g(1,s(2)).ofs(",");
d.t().rt("r").m("K","rook","*")
;resets evaluation to the original stdin for the next statement- only the last statement is printed by default
--print-allprints all statement results separated by----Fsets the initial record-modefsbefore the DSL runs, and accepts regex patterns
Record functions
fs(re)input field separator regex, AWK-like (\s+by default)rs(sep)input record separator (\nby default)ofs(sep)output field separator (by default)ors(sep)output record separator (\nby default)p(...)/select(...)select fields, e.g.p(1,"3:")sb(re, rep)/replace(re, rep)regex replace per celln(start_or_AZ)/enum(...)prepend numbering orA-Zcycle labelsx(col, sep)/explode(...)split one field into multiple rowsi(key_col, val_col, join_sep?)/implode(...)collapse rows by keyg(key_col, agg...)/groupby(...)aggregate by keysh(mode, ...)/reshape(...)where mode isw2lorl2wf(template?)/flatten(...)flatten records; optional template like"{name}:{age}"
Aggregators
s(col)/sum(col)c()/count()mn(col)/min(col)mx(col)/max(col)a(col)/avg(col)
Grid functions
fs(sep)optional cell separator; default is character gridrs(sep)/ofs(sep)/ors(sep)t()/transpose()rt("r"|"l"|"180")/rotate(...)m(from, ray, put)marks along a ray (rook,bishop,queen,8)m(from, through_re, to, put)8-direction pattern mark, useful for reversi-like scans
Examples
Record functions
-F re / --field-separator re
Sets the initial record-mode field separator from the CLI before any DSL method runs.
Input:
A,10;tokyo
B:20;osaka
Command:
|
Output:
A|10|tokyo
B|20|osaka
fs(re)
Splits each record with the given regex instead of the default whitespace separator.
Input:
A,10
B,20
Command:
|
Output:
A 10
B 20
rs(sep)
Treats the given separator as the boundary between input records.
Input:
A 10|B 20|
Command:
|
Output:
A 10
B 20
ofs(sep)
Changes the separator used when fields are joined for output.
Input:
A 10
B 20
Command:
|
Output:
A,10
B,20
ors(sep)
Changes the separator used when output records are joined together.
Input:
A 10
B 20
Command:
|
Output:
A 10|B 20|
p(...) / select(...)
Keeps only the requested fields and removes the rest.
Input:
A 10 tokyo
B 20 osaka
Command:
|
Output:
A tokyo
B osaka
sb(re, rep) / replace(re, rep)
Replaces text matching the regex in every cell.
Input:
A-10
B-20
Command:
|
Output:
A-XX
B-XX
n(start_or_AZ) / enum(...)
Adds a numeric counter column to the front of each row.
Input:
A 10
B 20
Command:
|
Output:
1 A 10
2 B 20
Uses alphabet labels instead of numbers and prepends them as a new first column.
Input:
A 10
B 20
C 30
Command:
|
Output:
A A 10
B B 20
C C 30
x(col, sep) / explode(...)
Splits one field into multiple rows while keeping the other columns as-is.
Input:
A,10;20;30
B,7;8
Command:
|
Output:
A,10
A,20
A,30
B,7
B,8
i(key_col, val_col, join_sep?) / implode(...)
Merges rows with the same key by joining one value column into a single field.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 10,20
B 7
g(key_col, agg...) / groupby(...)
Groups rows by the key column and emits aggregate results per group.
Input:
A,10;20;30
B,7;8
Command:
|
Output:
A,60
B,15
sh("w2l", ...) / reshape(...)
Turns wide columns into repeated long-form rows.
Input:
name math eng
A 80 90
B 70 85
Command:
|
Output:
A math 80
A eng 90
B math 70
B eng 85
sh("l2w", ...) / reshape(...)
Turns repeated long-form rows back into a wide table.
Input:
A math 80
A eng 90
B math 70
B eng 85
Command:
|
Output:
key eng math
A 90 80
B 85 70
f(template?) / flatten(...)
Renders each data row as a single string using the header names in the template.
Input:
name age
alice 20
bob 30
Command:
|
Output:
alice:20
bob:30
Aggregators
s(col) / sum(col)
Sums the numeric values in the target column for each group.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 30
B 7
c() / count()
Counts how many rows belong to each group.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 2
B 1
mn(col) / min(col)
Takes the smallest numeric value in the target column for each group.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 10
B 7
mx(col) / max(col)
Takes the largest numeric value in the target column for each group.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 20
B 7
a(col) / avg(col)
Computes the average numeric value in the target column for each group.
Input:
A 10
A 20
B 7
Command:
|
Output:
A 15
B 7
Grid functions
fs(sep)
Treats each input row as separator-delimited cells instead of a character grid.
Input:
a,b,c
d,e,f
Command:
|
Output:
a|b|c
d|e|f
rs(sep)
Treats the given separator as the boundary between grid rows.
Input:
abc|def|ghi|
Command:
|
Output:
abc
def
ghi
ofs(sep)
Changes the separator used when cells are joined for each output row.
Input:
abc
def
Command:
|
Output:
a|b|c
d|e|f
ors(sep)
Changes the separator used when output rows are joined together.
Input:
abc
def
Command:
|
Output:
abc---
def---
t() / transpose()
Swaps rows and columns in the grid.
Input:
abc
def
ghi
Command:
|
Output:
adg
beh
cfi
rt("r"|"l"|"180") / rotate(...)
Rotates the grid 90 degrees clockwise.
Input:
abc
def
ghi
Command:
|
Output:
gda
heb
ifc
Rotates the grid by 180 degrees.
Input:
abc
def
ghi
Command:
|
Output:
ihg
fed
cba
m(from, ray, put)
Marks all reachable cells along the specified ray directions from the source cell.
Input:
.....
..K..
.....
Command:
|
Output:
..*..
**K**
..*..
m(from, through_re, to, put)
Marks only the matching middle cells when they are sandwiched between from and to.
Input:
.....
.XOOX
.....
Command:
|
Output:
.....
.X**X
.....
Multiple statements
Runs each statement against the original stdin, so later statements do not receive earlier output.
Input:
A 10,20
B 7,8
Command:
|
Output:
A 30
B 15
---
1 A 10,20
2 B 7,8
Notes
fsis treated as a regex for record mode, similar to AWKFS- CSV quoting is not implemented; this prototype is regex-split based
;resets to the original stdin; it does not pass the previous statement result to the next one- grid mode defaults to character cells;
d.fs(",")switches to separated cells