% MGK(1) % NAKAMURA Yoshitaka % Apr 2017
mangekyo - lenses within pipes
mangekyo is a tool to process JSON and other format of data stream, through lenses within pipes.
mangekyo is written by haskell. You can use stack to build and install it.
$ cd mangekyo
$ stack setup
$ stack install
hello world:
$ mgk 'yield "hello world"`
"hello world"
extract name
from JSON stream:
$ echo '{"name":"roi"}{"name":"zak"}' | mgk 'map { _^.@name }'
"roi"
"zak"
extract from nested object:
$ echo '{"user":{"name":"nakamuray"}}' | mgk 'map { _^.@user.@name }'
"nakamuray"
sum value
:
$ echo '{"value":1}{"value":2}{"value":3}' | mgk 'map { _^.@value } | each { @sum += _ }; yield sum'
6
sum value
, functional way:
$ echo '{"value":1}{"value":2}{"value":3}' | mgk 'map { _^.@value } | fold (+) 0 & yield'
6
"hello world"
"\u3042\u3044\u3046\u3048\u304a"
42
10.1
true
false
null
[1, 2, 3]
{"key": "value"}
(1, 2, 3)
x -> y -> { x + y }
{ _ + 1 }
# function call
f x
f x y
@x
at "x"
Convert value
to string.
Convert value
to number.
Convert value
to bool.
Negate boolean value
.
If bool
is true value, then call then_function
, else call else_function
.
If bool
is true value, then call function
.
If bool
is false value, call function
.
Do nothing.
Exit with return code.
Return value
as is.
Return function which return value
Call function
for each array
element, return array of return values.
Return array of (key, value) tuple.
Format string with namespace variables.
$ mgk '@name .= "world"; yield $ fmt "hello #{name}"'
"hello world"
Split string
by sep_string
.
Negate a number
.
Return length of value
.
Display string to terminal (stderr).
Display string to terminal (stderr), without newline.
Execute system command and return exit status.
Print value
directly (for debug purpose)
Compose functions (or lenses).
Apply function
to the value
.
Apply function
to the value
.
Add values.
TODO.
TODO.
Left value
equal right value
.
Left value
greater than right value
.
Left value
less than right value
.
Left value
greater than equal right value
.
Left value
less than equal right value
.
When string
match regex_string
, return array of matched string and captures.
if not, return null.
Not match the string. this function return bool.
In addition to return value, functions could have side effects: consume values from upstream, and produce value to downstream.
By default, upstream is stdin
and downstream is stdout
.
You can use |
to join functions, in such case left one is upstream and right
one is downstream.
Send a value
downstream.
$ mgk 'yield 42'
42
Wait for a value from upstream.
$ seq 10 | mgk 'yield $ await()'
1
Fold input stream to value.
$ seq 3 | mgk '@r .= fold (+) 0; yield r'
6
Apply function
to all values in a stream.
$ seq 3 | mgk 'map { _ * 2 }'
2
4
6
Filter stream by predicate function
.
$ seq 5 | mgk 'filter { _ < 3 }'
1
2
Exclude stream by predicate function
.
$ seq 5 | mgk 'exclude { _ < 3 }'
3
4
5
Apply function
for each value in a stream.
Don't pass result values to downstream, by itself.
$ seq 3 | mgk 'each { _ * 2 }'
$ seq 3 | mgk 'each { yield $ _ * 2 }'
2
4
6
Convert stream of array of value, to stream of value.
$ mgk 'yield [1, 2, 3]'
[
1,
2,
3
]
$ mgk 'yield [1, 2, 3] | concat()'
1
2
3
Consume all values from stream and return as a array.
$ seq 3 | mgk '@a .= consume(); yield a'
[
1,
2,
3
]
Map a function
and concat a result.
$ seq 3 | mgk 'concatMap { [_, _] }'
1
1
2
2
3
3
Map a function
and filter a result.
Only true values are passed to downstream.
$ echo '{"value":1}' '{}' | mgk 'filterMap { _ ^. @value }'
1
Isolate given number of items to downstream.
$ seq 10 | mgk 'isolate 3'
1
2
3
Group a stream into chunks of given size.
$ seq 4 | mgk 'chunksOf 2'
[
1,
2
]
[
3,
4
]
Produce an infinite stream of repeated application of function to value.
$ mgk 'iterate { _ + 1 } 0'
1
2
3
4
...
Call a function and merge it as a stream to upstream.
$ seq 3 | mgk 'mergeSource { yield "a"; yield "b" }'
[
"a",
1
]
[
"b",
2
]
Alias for mergeSource
.
Provide every values from upstream to both functions. Return result of both functions.
$ seq 5 | mgk '@r .= zipConduit { fold (+) 0 } { fold (*) 1 }; yield r'
[
15,
120
]
Alias for zipConduit
.
Provide each element of array to downstream.
$ mgk 'sourceArray [1, 2, 3]'
1
2
3
Alias for sourceArray
.
Get back a value to upstream, which to be consumed by next component.
$ seq 3 | mgk 'leftover 10; map { _ * 2 }'
20
2
4
6
Replicate a value given number of times, provide those to downstream.
$ mgk 'replicate 3 "hello"'
"hello"
"hello"
"hello"
Look at the next value in the upstream.
mangekyo uses lens to get/set value from/to object and array. It also use lens to modify namespace object.
Create a lens
of given value
.
View object
or array
using lens
.
$ mgk 'yield $ view {"key": "value"} @key'
"value"
$ mgk 'yield $ view [1, 2, 3] @1'
2
Set value
to object
or array
using lens
.
$ mgk 'yield $ set @key "value" {}'
{
"key": "value"
}
Call function
over the value lens views, replace it with result value.
$ mgk 'yield $ over @key { _ + 1 } {"key": 1}'
{
"key": 2
}
Setter for each element of array.
$ mgk 'yield $ set mapped 42 [1, 2, 3]'
[
42,
42,
42
]
$ mgk 'yield $ over mapped { _ + 1 } [1, 2, 3]'
[
2,
3,
4
]
Opereter version of view
.
$ mgk 'yield $ {"key": "value"} ^. @key'
"value"
$ mgk 'yield $ [1, 2, 3] ^. @1'
2
Operator version of set
.
$ mgk 'yield $ (@key .~ "value") {}'
{
"key": "value"
}
$ mgk 'yield $ {} & @key .~ "value"'
{
"key": "value"
}
Operator version of over.
$ mgk 'yield $ (@key %~ { _ + 1 }) {"key": 1}'
{
"key": 2
}
$ mgk 'yield $ {"key": 1} & @key %~ { _ + 1 }'
{
"key": 2
}
set
to the target of lens within namespace object.
$ mgk '@x .= 10; yield x'
10
over
to the target of lens within namespace object.
$ mgk '@x .= 10; @x %= { _ + 1 }; yield x'
11
Add value
to the target of lens within namespace object.