Reputation: 24092
I'd like to run jq
on every line matching a specific pattern, I tried:
:g/^\s\+{/!jq .
where ^\s+{
is my pattern but it doesn't work. I get a lot of errors like this:
...
:!jq .
[No write since last change]
:!jq .
[No write since last change]
...
I can use something like:
g/^\s\+{/p
which will work and will print all of the lines matching my pattern.
Any suggestions?
Upvotes: 1
Views: 307
Reputation: 172510
If I understand you correctly, you have a file with multiple JSON documents, each one concatenated on a single line, and you now want to pretty-print each such document into indented, multi-line ones with jq .
What you do with :g/^\s\+{/
is locating lines with JSON documents, and then executing the command on it. The problem is in the :!jq .
The way I've written it, you may already recognize that this is :help :!cmd
, whereas you've intended to filter the current line (a JSON document spread over multiple subsequent lines would also work, but require a range). The filtering command is subtly different; :help :range!
.
So, with :!jq .
, Vim just launches the external jq
with the .
argument, but it doesn't pass anything from the buffer to it. That's why jq
is just sitting there and waiting for input until you abort it (e.g. with <C-c>
).
The :.!jq .
command instead passes the current line :.
as a range to the jq
command, and then replaces the original line with the command's output, just as you want. Adding that single .
fixes your command:
:g/^\s\+{/.!jq .
Upvotes: 4