To delete the .packages.code
key and its value, using jq
:
jq 'del(.packages.code)' file.json
To delete any entry under .packages
whose .name
key has the value code
:
jq 'del(.packages[] | select(.name == "code"))' file.json
The same two commands, but they take the code
string from a shell variable:
string=code
jq --arg key "$string" 'del(.packages[$key])' file.json
jq --arg key "$string" 'del(.packages[] | select(.name == $key))' file.json
Redirect the output to a new file and replace the old file with that if it looks ok.
Assuming that the input looks like
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}
(Note that I have fixed the broken JSON on the lines that have JSON objects.)
... then you can extract the lines that you want with grep
:
grep '^{' file
or
grep -v -F '[SUCCESS]' file
or similar grep
command.
You may then parse the stream of JSON objects using jq -s
, which will automatically read them into an array. This allows you do the processing of the data like so:
grep '^{' file | jq -s 'map({ alias1: .field1, alias2: .field3 })'
With the input shown above in file
, this would generate
[
{
"alias1": "value11",
"alias2": "value13"
},
{
"alias1": "value21",
"alias2": "value23"
}
]
If you are uninterested in changing your already existing initial parsing of the input and want to put your output into an array, then it's just a matter of passing it through jq -s .
:
$ cat file
{ "alias1": "value11", "alias2": "value13" }
{ "alias1": "value21", "alias2": "value23" }
$ jq -s . file
[
{
"alias1": "value11",
"alias2": "value13"
},
{
"alias1": "value21",
"alias2": "value23"
}
]
A hack to read directly from the original file with jq
is to read the data as raw strings, try to convert them into valid JSON, and then throw away any errors:
$ cat file
[1] 14:44:51 [SUCCESS] 1.1.1.1
{"field1":"value11","field2":"value12","field3":"value13"}
[2] 14:44:51 [SUCCESS] 1.1.1.2
{"field1":"value21","field2":"value22","field3":"value23"}
$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null
{
"alias1": "value11",
"alias2": "value13"
}
{
"alias1": "value21",
"alias2": "value23"
}
This could then be gathered in an array:
$ jq -R 'fromjson | { alias1: .field1, alias2: .field3 }' file 2>/dev/null | jq -s .
[
{
"alias1": "value11",
"alias2": "value13"
},
{
"alias1": "value21",
"alias2": "value23"
}
]
Note that we need the two separate invocations of jq
here as the first jq
invocation would terminate prematurely if it tried to convert the input into JSON with fromjson
into an array (or any other structure other than individual objects).
Best Answer
Using
select()
withwith_entries()
to select only the key that you want:Parametrised so that it takes the wanted key from the command line:
Change the
==
to!=
to delete the named key.Note that your own attempt does not distinguish where the key is found in the document, which could cause some confusion in the general case.
Just to add a bit more explanation as to what's happening in the
jq
expression.Within the
with_entries()
command, what's visible is the following set of objects, each with akey
and avalue
key:The
select()
call extracts each object for which the given test is true, and discards the rest. Our test is simply "Is the value of thekey
key the stringreg2.io
?".A call to
with_entries(expr)
is equivalent toto_entries | map(expr) | from_entries
.