4

What shell command in a bash script could be issued to efficiently strip all the decimal places from the numbers in a JSON file such as this:

    [
        {
            "IMSKU": "1000001", 
            "AttributeID": 7332.0, 
            "Value": "McAfee Host Intrusion Prevention for Desktops safeguards your business against complex security threats that may otherwise be unintentionally introduced or allowed by desktops and laptops. Host Intrusion Prevention for Desktops is easy to deploy, configure, and manage.", 
            "Unit": null, 
            "StoredValue": null, 
            "StoredUnit": null, 
            "Name": "Marketing text", 
            "Format": "1", 
            "Position": "1", 
            "Group_Name": "Basic Specification", 
            "AGGroup_Position": 0.0, 
            "Product_Hierarchy": 15198001453.0
        }, 
        {
            "IMSKU": "1000001", 
            "AttributeID": 7343.0, 
            "Value": "May 2013", 
            "Unit": null, 
            "StoredValue": null, 
            "StoredUnit": null, 
            "Name": "PI Date", 
            "Format": "1", 
            "Position": "1", 
            "Group_Name": "PI DATE", 
            "AGGroup_Position": 1.0, 
            "Product_Hierarchy": 15198001453.0
        }, 
        {
            "IMSKU": "1000001", 
            "AttributeID": 7344.0, 
            "Value": "McAfee", 
            "Unit": null, 
            "StoredValue": "0.00", 
            "StoredUnit": null, 
            "Name": "Brand Name", 
            "Format": "3", 
            "Position": "1", 
            "Group_Name": "PRODUCT", 
            "AGGroup_Position": 2.0, 
            "Product_Hierarchy": 15198001453.0
        }
    ]

So that

"AttributeID":  7344.0

would become

"AttributeID":  7344

for example, and so forth.

5
  • Note that there is no difference semantically; JSON only has a single "number" type. – chrylis -cautiouslyoptimistic- Dec 23 '19 at 5:54
  • that's not an array – Jasen Dec 23 '19 at 6:36
  • @Jasen I see. So what would you call it...? – ptrcao Dec 23 '19 at 8:01
  • 1
    json.org/json-en.html - curly brackets mean it's an object. – Jasen Dec 23 '19 at 8:18
  • @Jasen I humbly defer to your knowledge; if this warrants a correction in the original title and post, feel free to exercise your editorial privileges. – ptrcao Dec 23 '19 at 8:35
11

Just running it through the identity filter with jq reformats the numbers that has a .0 decimal as integers:

$ jq . file.json
[
  {
    "IMSKU": "1000001",
    "AttributeID": 7332,
    "Value": "McAfee Host Intrusion Prevention for Desktops safeguards your business against complex security threats that may otherwise be unintentionally introduced or allowed by desktops and laptops. Host Intrusion Prevention for Desktops is easy to deploy, configure, and manage.",
    "Unit": null,
    "StoredValue": null,
    "StoredUnit": null,
    "Name": "Marketing text",
    "Format": "1",
    "Position": "1",
    "Group_Name": "Basic Specification",
    "AGGroup_Position": 0,
    "Product_Hierarchy": 15198001453
  },

(etc.)

If there are numbers with decimals that are not zero, and you want to remove these too, use

jq '(.. | select(type == "number" )) |= floor' file.json

This would apply the floor function on all numbers whatsoever in the data, rounding them down to the closest integer.

To also investigate whether there are strings that contain digits after a dot at the very end, and remove these digits (and the dot):

jq '(.. | select(type == "string")) |= sub("\\.[0-9]+$"; "")' file.json

The affected entries would still be strings and are not converted to a numerical type.

6
  • What about for "StoredValue": "0.00",? jq . file.json seems to leave these untouched? – ptrcao Dec 22 '19 at 17:58
  • 1
    @ptrcao When you said numbers, I only considered the numbers. "0.00" is technically a string. Do you want to modify these too and at the same time change the type of them to number? This may impact any program reading the data. – Kusalananda Dec 22 '19 at 18:00
  • Yes, for this example, suppose I wanted also to drop the decimals on instances of "0.00". If later that creates problems, I can just not use this part of the solution. Although you are technically right, it's a string and not a part of the original question. Let's consider it for educational purposes. – ptrcao Dec 22 '19 at 18:02
  • 1
    @ptrcao Sorry, I was called away. See updated answer. – Kusalananda Dec 22 '19 at 18:28
  • 1
    @ptrcao Then it would be safest to only modify the values corresponding to the specific keys that you know you want to modify rather than relying on heuristics. It's 1.30AM here and I need to sleep, but I might get back to this tomorrow and write an example for that too. – Kusalananda Dec 23 '19 at 0:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.