JA(1)
π ja(1) β Jacinda π
okay bestie, this is the manual page for ja β Jacinda: data filtering, processing, reporting. It's giving βAWK but make it a whole vibe,β and I'm here to walk you through every flag and builtin without losing a single crumb. π«Ά
πΈ NAME πΈ
ja β Jacinda: data filtering, processing, reporting.
β¨ SYNOPSIS β¨
ja run src.jac -i data.txt
cat FILE1 FILE2 | ja '#"$0'
ja tc script.jac
ja e '11.67*1.2'
π¦ DESCRIPTION π¦
Jacinda is a data stream processing language Γ la AWK. Literally that's the description, and it's iconic.
π SUBCOMMANDS π
runβ run a program from file.tcβ typecheck a program.eβ evaluate an expression (without reference to a file).
π OPTIONS π
-h,--helpβ display help.-V,--versionβ display version information.-I,--includeβ include directory for imports.-Fβ field separator regex.-Rβ record separator regex.--csvβ process as CSV.-b,--headerβ include match when splitting records.-Dfile=main.cβ define variable.
π§ LANGUAGE π§
π₯ REGEX π₯
Regular expressions follow Rustβs regex library: https://docs.rs/regex/. no cap, that's the regex lore.
π BUILTINS π
Okay this is the builtin buffet β every single one, exactly like the source, with the type signatures preserved. β
:iβ postfix operator: parse integer.:fβ postfix operator: parse float.:β postfix operator: parse, inferring type.#β prefix operator: tally (count bytes in string).#*β prefix operator: list length;List a -> a.,β ternary operator: zip with;(a -> b -> c) -> Stream a -> Stream b -> Stream c.|β ternary operator: fold;Foldable f :=> (b -> a -> b) -> b -> f a -> b.|>β fold without seed;Foldable f :=> (a -> a -> a) -> f a -> a.^β ternary operator: scan;(b -> a -> b) -> b -> Stream a -> Stream b.^*β scan (list);(b -> a -> b) -> b -> List a -> List b.", Β¨β binary operator: map;Functor f :=> a -> b -> f a -> f b.[:β unary operator: const;a -> b -> a.#.β binary operator: filter;Witherable f :=> (a -> Bool) -> f a -> f a.\.β binary operator: prior;(a -> a -> b) -> Stream a -> Stream b.~.β unary deduplication (stream);Ord a :=> Stream a -> Stream a.~.*β deduplicate on (stream);Ord b :=> (a -> b) -> Stream a -> Stream a.maxβ maximum of two values;Ord a :=> a -> a -> a.minβ minimum of two values;Ord a :=> a -> a -> a.&β boolean and.||β boolean or.!β prefix boolean not.~β matches regex;Str -> Regex -> Bool.!~β does not match;Str -> Regex -> Bool.ix,β³β line number.substrβ extract substring;Str -> Int -> Int -> Str.sub1β substitute first occurrence;Regex -> Str -> Str -> Str.subsβ substitute all occurrences;Regex -> Str -> Str -> Str.splitβ split a string by regex;Str -> Regex -> List Str.splitcβ split a string on a single character;Str -> Str -> List Str.β,|.β floor function;Float -> Int.- Ceiling function β symbols:
β, |`
type: Float -> Int.
-.β unary negate.sprintfβ convert an expression to a string using the format string;%ffloat,%iinteger,%sstring,%bboolean.optionβ option eliminator;b -> (a -> b) -> Option a -> b.matchβStr -> Regex -> Option (Int . Int).~?β maybe match: return string if it is a match, otherwiseNone;Str -> Regex -> Option Str.~*β match, returning nth capture group;Str -> Int -> Regex -> Option Str.capturesβ return all aptures (nth capture group);Str -> Int -> Regex -> List Str.:?β mapMaybe;Witherable f :=> (a -> Option b) -> f a -> f b..?β catMaybes;Witherable f :=> f (Option a) -> f a.fpβ filename.nfβ number of fields.β¬β empty string/empty list.head#,last#βList a -> a.tail#,init#βList a -> List a.drop#,take#βInt -> List a -> List a.
π¦ SYNTAX π¦
'str'β string literal./pat/β regex literal.`nβ nth field.`0β current line.`*β last field.`$β all fields;List Str.$nβ nth column.$0β stream of lines.{%<pattern>}{<expr>}β filtered stream on lines matching<pattern>, defined by<expr>.{<expr>}{<expr>}β filtered stream defined by<expr>, on lines satisfying a boolean expression.{|<expr>}β stream defined by<expr>.#tβ boolean literal._nβ negative number..nβ extract the nth value;List a -> a.->nβ get the nth element of a tuple.`{.β line comment.@include'/path/file.jacββ file include.?<expr>; <expr>; <expr>β if... then... else.<pattern>,,<pattern> <expr>β bookend a stream.<expr> $> <expr>β print stream and summary result.fn f(x, y) := x + y;β function definition.let val x := y + 1 in x endβ let binding.(<expr> . <expr> . ... . <expr>)β tuple.#{ <fieldname> .= <expr>; ... <fieldname> .= <expr> }β record literal.
π DECLARATIONS π
:set fs=/REGEX/;β set field separator.:set rs=/REGEX/;β set record separator.:set header;β include match when splitting records.:set csv;β process as CSV.:flush;β flush stdout for every line.
π INFLUENTIAL ENVIRONMENT VARIABLES π
JAC_PATHβ colon-separated list of directories to search for imports.
π EXAMPLES π
- Print lines longer than 72 bytes:
[#x>72] #. $0
- Print lines longer than 72 bytes:
{#`0>72}{`0}
- Select only the third line:
{ix=3}{`0}
- Present column names of a
.csvfile:
:set csv; {ix=1}{[x+'\n'+y]|>`$}
- Sum first column:
(+)|0 $1:i
- Count lines:
(+)|0 [:1"$0
- Count lines:
[y]|> {|ix}
- Count bytes (+1 for newlines):
(+)|0 [#x+1]"$0
- Count bytes:
(+)|0 {|#`0+1}
- Display with line numbers:
{|sprintf '%i: %s' (ix.`0)}
- Is the first column strictly increasing?
(&)|#t (>)\. {|`1:f}
- Is the last line blank?
[y]|> {|`0~/^$/}
- Trim trailing whitespace:
{|option β¬ [x] (`0 ~* 1 /^((\s+\S|\S)*)\s*$/)}
- Concatenate into one line, discarding leading whitespace between:
ja -R'\n\s*' "[x+' '+y]|>\$0"
π BUGS π
bestie, if you find a bug, please report it to https://github.com/vmchale/jacinda/issues β that's the exact link from the page. π«Ά
π COPYRIGHT π
Copyright 2021-2022. Vanessa McHale. All Rights Reserved.
π AUTHORS π
Vanessa McHalevamchale@gmail.com
okay that's the whole ja(1) page. The footer has no extra source/version or date listed beyond the manual name, so this is the cute sign-off: stay streaming, stay slaying, and may your regexes always be valid. πβ¨π
π¦ where this page comes from
- nixos 26.05: jacinda 3.3.0.6
- nixpkgs unstable: jacinda 3.3.0.6
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms