JSON Mode
Composability is a key perk of command line tooling. ast-grep is no exception.
--json will output results in JSON format. This is useful to pipe the results to other tools.
Example:
ast-grep run -p 'Some($A)' -r 'None' --jsonOutput Data Structure
The format of the JSON output is an array of match objects. Below is an example of a match object generated from the command above.
[
{
"text": "Some(matched)",
"range": {
"byteOffset": { "start": 10828, "end": 10841 },
"start": { "line": 303, "column": 2 },
"end": { "line": 303, "column": 15 }
},
"file": "crates/config/src/rule/mod.rs",
"lines": " Some(matched)",
"replacement": "None",
"replacementOffsets": { "start": 10828, "end": 10841 },
"language": "Rust",
"metaVariables": {
"single": {
"A": {
"text": "matched",
"range": {
"byteOffset": { "start": 10833, "end": 10840 },
"start": { "line": 303, "column": 7 },
"end": { "line": 303, "column": 14 }
}
}
},
"multi": {},
"transformed": {}
}
}
]Match Object Type
Below is the equivalent TypeScript type definition of the match object.
interface Match {
text: string
range: Range
file: string // relative path to the file
// the surrounding lines of the match.
// It can be more than one line if the match spans multiple ones.
lines: string
// optional replacement if the match has a replacement
replacement?: string
replacementOffsets?: ByteOffset
metaVariables?: MetaVariables // optional metavars generated in the match
}
interface Range {
byteOffset: ByteOffset
start: Position
end: Position
}
// UTF-8 encoded byte offset
interface ByteOffset {
start: number // start is inclusive
end: number // end is exclusive
}
interface Position {
line: number // zero-based line number
column: number // zero-based column number
}
// See Pattern doc
interface MetaVariables {
single: Record<String, MetaVar>
multi: Record<String, MetaVar[]>
transformed: Record<String, String> // See Rewrite doc
}
interface MetaVar {
text: string
range: Range
}For more information about MetaVariables and transformed fields, see the Pattern and Rewrite documentation.
If you are using lint rule to find matches, the generated match objects will have several more fields.
interface RuleMatch extends Match {
ruleId: string
severity: Severity
note?: string
message: string
}
enum Severity {
Error = "error",
Warning = "warning",
Info = "info",
Hint = "hint",
}line, column, and byte offset are zero-based
The line, column, and byteOffset fields are zero-based. This means that the first line, column, and byte offset are 0, not 1. The design is consistent with the LSP and tree-sitter specifications.
If you need 1-based numbers, you can use jq to transform the output.
Consuming JSON output
ast-grep embraces the Unix philosophy of composability. The --json flag is designed to make it easy to pipe the results to other tools.
For example, you can use jq to extract information from the results and render it in jless.
ast-grep run -p 'Some($A)' -r 'None' --json | jq '.[].replacement' | jlessYou can also see an example of using --json flag in Vim's QuickFix window.
Output Format
By default, ast-grep prints the matches in a JSON array that is formatted with indentation and line breaks. --json is equivalent to --json=pretty. This makes it easy to read the output by humans. However, this might not be suitable for other programs that need to process the output from ast-grep. For example, if there are too many matches, the JSON array might be too large to fit in memory.
To avoid this problem, you can use the --json=stream option when running ast-grep. This option will make ast-grep print each match as a separate JSON object, followed by a newline character. This way, you can stream the output to other programs that can read one object per line and parse it accordingly.
The output of --json=stream looks like below:
$ ast-grep -p pattern --json=stream
{"text":"Some(matched)", ... }
{"text":"Some(matched)", ... }
{"text":"Some(matched)", ... }You can read the output line by line and process it accordingly.
--json accepts one of the following values: pretty, stream, or compact.
--json=stream requires the equal sign
You have to use --json=<STYLE> syntax when passing value to the json flag. A common gotcha is missing the equal sign. --json stream is parsed as --json=pretty stream and stream is parsed as a directory. Only --json=stream will work as a key-value pair.