jless can read files directly, or read JSON data from standard input:
jless can handle newline-delimited JSON, so feel free to pipe in the output from jq or some dense log files.
jless can also handle YAML data, either automatically by detecting
the file extension, or by explicitly passing the --yaml
flag.
If you frequently view YAML data, we suggest the following alias:
jless has a large suite of vim-inspired commands. Commands prefixed by
count may be preceded by a number N
, which will
perform a command a given number of times.
q
, Ctrl-C
, :quit
, :exit
Exit jless; don't worry, it's not as hard as exiting vim.:help
, F1
Show the help page.j
, DownArrow
, Ctrl-n
, Enter
Move focus down one line (or N
lines).k
, UpArrow
, Ctrl-p
, Backspace
Move focus up one line (or N
lines).h
, LeftArrow
When focused on an expanded object or array, collapse the object or
array. Otherwise, move focus to the parent of the focused node.
H
Focus the parent of the focused node without collapsing the focused node.l
, RightArrow
When focused on a collapsed object or array, expand the object or array.
When focused on an expanded object or array, move focus to the first
child. When focused on non-container values, does nothing.
J
Move to the focused node's next sibling 1 or N
times.K
Move to the focused node's previous sibling 1 or N
times.w
Move forward until the next change in depth 1 or N
times.b
Move backwards until the next change in depth 1 or N
times.Ctrl-f
, PageDown
Move down by one window's height or N
windows' heights.Ctrl-b
, PageUp
Move up by one window's height or N
windows' heights.0
, ^
Move to the first sibling of the focused node's parent.$
Move to the last sibling of the focused node's parent.Home
Focus the first line in the inputEnd
Focus the last line in the inputg
Focus the first line in the input if no count is given. If a count is given, focus
that line number. If the line isn't visible, focus the last visible line before it.
G
Focus the last line in the input if no count is given. If a count is given, focus
that line number, expanding any of its parent nodes if necessary.
c
Shallow collapse the focused node and all its siblings.C
Deep collapse the focused node and all its siblings.e
Shallow expand the focused node and all its siblings.E
Deep expand the focused node and all its siblings.Space
Toggle the collapsed state of the currently focused node.Ctrl-e
Scroll down one line (or N
lines).Ctrl-y
Scroll up one line (or N
lines).Ctrl-d
Scroll down by half the height of the screen (or by N
lines).Ctrl-u
Scroll up by half the height of the screen (or by N
lines). For
this command and Ctrl-d
, focus is also moved by the
specified number of lines. If no count is specified, the number of
lines to scroll by is recalled from previous executions.
zz
Move the focused node to the center of the screen.zt
Move the focused node to the top of the screen.zb
Move the focused node to the bottom of the screen..
Scroll a truncated value one character to the right (or N
characters).,
Scroll a truncated value one character to the left (or N
characters).;
Scroll a truncated value all the way to the end, or, if already at
the end, back to the start.
<
Decrease the indentation of every line by one (or N
) tabs.>
Increase the indentation of every line by one (or N
) tabs.You can copy various parts of the JSON file to your clipboard using
one of the following y
commands.
Alternatively, you can print out values using p
. This is useful
for viewing long string values all at once, or if the clipboard functionality
is not working; mouse-tracking will be temporarily disabled, allowing you
to use your terminal's native clipboard capabilities to select and copy
the desired text.
yy
, pp
Copy/print the value of the currently focused node, pretty printedyv
, pv
Copy/print the value of the currently focused node in a "nicely" printed one-line formatys
, ps
When the currently focused value is a string, copy/print the contents of the
string unescaped (except control characters)
yk
, pk
Copy/print the key of the current key/value pairyp
, pP
Copy/print the path from the root JSON element to the currently focused
node, e.g., .foo[3].bar
yb
, pb
Like yp
, but always uses the bracket form for object keys,
e.g., ["foo"][3]["bar"]
, which is useful if the environment
where you'll paste the path doesn't support the .key
format,
like in Python
yq
, pq
Copy/print a jq
style path that will select the currently focused
node, e.g., .foo[].bar
jless supports full-text search over the input JSON.
/pattern
Search forward for the given pattern, or to its N
th occurrence.
?pattern
Search backwards for the given pattern, or to its N
th previous occurrence.
*
Move to the next occurrence of the object key on the focused line
(or move forward N
occurrences).
#
Move to the previous occurrence of the object key on the focused line
(or move backwards N
occurrences).
n
Move in the search direction to the next match (or forward N
matches).
N
Move in the opposite of the search direction to the previous match
(or previous N
matches).
Searching uses "smart case" by default. If the input pattern doesn't
contain any capital letters, a case insensitive search will be
performed. If there are any capital letters, it will be case
sensitive. You can force a case-sensitive search by appending
/s
to your query.
A trailing slash will be removed from a pattern; to search for a
pattern ending in /
(or /s
), just add
another /
to the end.
Search patterns are interpreted as mostly standard regular
expressions, with one exception. Because JSON data contains many
square and curly brackets ([]{}
), these characters do
not take on their usual meanings (specifying characters
classes and repetition counts respectively) and are instead
interpreted literally.
To use character classes or repetition counts, escape these characters with a backslash.
Some examples:
/[1, 2, 3]
matches an array: [1, 2, 3]
/\[bch\]at
matches bat
, cat
or hat
/{}
matches an empty object {}
/(ha)\{2,3\}
matches haha
or hahaha
For exhaustive documentation of the supported regular expression syntax, check out the documentation of the underlying regex engine:.
The search is not performed over the original input, but over a single-line pretty formatted version of the input JSON. Consider the following two ways to format an equivalent JSON blob:
jless will create an internal representation formatted as follows:
(No spaces inside empty objects or arrays, one space inside objects with values, no spaces inside array square brackets, no space between an object key and ':', one space after the ':', and one space after commas separating object entries and array elements.)
Searching will be performed over this internal representation so that patterns can include multiple elements without worrying about newlines or the exact input format.
When the input is newline-delimited JSON, an actual newline will separate each top-level JSON element in the internal representation.
jless starts in "data" mode, which displays the JSON data in a more streamlined fashion: no closing delimiters for objects or arrays, no trailing commas, no quotes around object keys that are valid identifiers in JavaScript. It also shows single-line previews of objects and arrays, and array indexes before array elements. Note that when using full-text search, object keys will still be surrounded by quotes.
By pressing m
, you can switch jless to "line" mode, which
displays the input as pretty printed JSON.
In line mode you can press %
when focused on an open or
close delimiter of an object or array to jump to its matching pair.
jless supports displaying line numbers, and does so by default. The line numbers do not reflect the position of a node in the original input, but rather what line the node would appear on if the original input were pretty printed.
jless also supports relative line numbers. When this is enabled, the
number displayed next to each line will indicate how many lines away it
is from the currently focused line. This makes it easier to use the
j
and k
commands with specified counts.
The appearance of line numbers can be configured via command line flags:
-n
, --line-numbers
Show absolute line numbers.
-N
, --no-line-numbers
Don't show absolute line numbers.
-r
, --relative-line-numbers
Show relative line numbers.
-R
, --no-relative-line-numbers
Don't show relative line numbers.
As well as at runtime:
:set number
Show absolute line numbers.
:set nonumber
Don't show absolute line numbers.
:set number!
Toggle whether showing absolute line numbers.
:set relativenumber
Show relative line numbers.
:set norelativenumber
Don't show relative line numbers.
:set relativenumber!
Toggle whether showing relative line numbers.
When just using relative line numbers, "0" will be displayed next to the currently focused line. When both flags are set, the absolute line number will be displayed next to the focused lines, and all other line numbers will be relative. This matches vim's behavior.