Wrap all numerics in JSON with quotes
$ jq 'map_values(tostring)' file.json
{
"id": "1",
"customer": "user",
"plate": "BMT-216-A",
"country": "GB",
"amount": "1000",
"pndNumber": "20000",
"zoneNumber": "4"
}
Redirect to a new file and then move that to the original filename.
For a more thorough conversion of numbers in non-flat structures into strings, consider
jq '(..|select(type == "number")) |= tostring' file.json
This would examine every value recursively in the given document, and select the ones that are numbers. The selected values are then converted into strings. It would also, strictly speaking, look at the keys, but since these can't be plain numbers in JSON, no key would be selected.
Example:
$ jq . file.json
{
"a": {
"b": 1
},
"b": null,
"c": [
1,
2,
"hello",
4
]
}
$ jq '(..|select(type == "number")) |= tostring' file.json
{
"a": {
"b": "1"
},
"b": null,
"c": [
"1",
"2",
"hello",
"4"
]
}
To additionally quote the null
, change the select()
to
select(type == "number" or type == "null")
here's an easy solution based on jtc
unix utility:
bash $ jtc -w'<.*>D:' -eu echo '"{}"' \; file.json
{
"amount": "1000",
"country": "GB",
"customer": "user",
"id": "1",
"plate": "BMT-216-A",
"pndNumber": "20000",
"zoneNumber": "4"
}
bash $
if you like to apply changes right into the json file, use the -f
switch, like this:
bash $ jtc -f -w'<.*>D:' -eu echo '"{}"' \; file.json
The proposed solution will work correctly with an arbitrary structured jsons, e.g.:
bash $ jtc -w'<.*>D:' -eu echo '"{}"' \; file.json
{
"amount": "1000",
"country": "GB",
"customer": "user",
"id": "1",
"plate": "BMT-216-A",
"pndNumber": "20000",
"sub": {
"subvalue": "123"
},
"zoneNumber": "4"
}
bash $
- if you like to quote null values, just throw in a walk-path
-w'<>n:'
- if you like to quote boolean values, throw in a walk-path
-w'<any>b:'
Also, the reverse task (unquote all the numerics) is easily achieved in the similar way: say, file.json
is already "enquoted", to unquote all the numerics:
bash $ jtc -w'<^\d+$>R:' -eu echo {-} \; file.json
{
"amount": 1000,
"country": "GB",
"customer": "user",
"id": 1,
"plate": "BMT-216-A",
"pndNumber": 20000,
"zoneNumber": 4
}
bash $
UPDATE: the latest version of jtc
implements now templates and namespaces. With that no invocation of external shell is required:
bash $ jtc -w'<.*>D:' -u'<.*>D:<val>v' -T'"{val}"' file.json
{
"amount": "1000",
"country": "GB",
"customer": "user",
"id": "1",
"plate": "BMT-216-A",
"pndNumber": "20000",
"zoneNumber": "4"
}
jtc
user guide: https://github.com/ldn-softdev/jtc/blob/master/User%20Guide.md
perl -pe 's/("(?:\\.|[^"])*")|[^\s[\]{}:,"]+/$1||qq("$&")/ge' file.json
Would quote anything that is not quoted and is not []{}:,whitespace
, so would quote numbers, true
, false
and null
.
perl -pe 's/("(?:\\.|[^"])*")|-?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?/$1||qq("$&")/ge'
Would specifically quote what matches the specification of a json number and that is not already inside quotes.
Those do an exact tokenising based on the JSON specification, it's not an approximation.