7

I am building a shell script that uses a JSON file.

{
  "property1": true,
  "list": [
    {
      "id": 1,
      "name": "APP1"
    },
    {
      "id": 2,
      "name": "APP2"
    }
  ],
  "property2": false
}

I need to use shell script to read the name from the list and remove its parent object from list. Basically I need to remove the object with name APP1 from the list using shell. Editing JSON structure is not an option.

3
  • 16
    Look into the jq tool. It's purpose is parsing JSON. The usual UNIX text processing tools are not suitable for context-free languages like JSON. Commented May 13, 2021 at 12:27
  • 2
    What do you (Sidharth) mean by "Editing JSON structure is not an option"?
    – David Z
    Commented May 13, 2021 at 21:52
  • use python - it's a scripting language that you can write shell scripts with: #!/usr/bin/env python3 - it has a json module with which you can load a json file into a dictionary object, manipulate it, then save it back to a file
    – Aaron F
    Commented May 13, 2021 at 23:00

4 Answers 4

30

Using the del function in jq:

jq 'del(.list[] | select(.name=="APP1"))'

If you wanted to pass the app name as a shell variable to jq you can use the --arg option:

jq --arg name "$name" 'del(.list[] | select(.name==$name))'
4

I would write the script using Python, which has JSON read/write functions built-in.

Given a file, myfile.json, containing the JSON object in the OP:

#!/usr/bin/env python  # Use the Python interpreter
from json import load, dump  # Import the JSON file read and write functions
with open("myfile.json", "r") as file_object:  # Open the JSON file for reading
    json_data = load(file_object)  # Load the data into a dictionary

new_list = [item for item in json_data["list"] if item["name"] != "APP1"]  # Make a new list without the item that should be removed
json_data["list"] = new_list  # Update the dictionary with the new list

with open("myfile.json", "w") as file_object:  # Open the JSON file for writing and truncate it
    dump(json_data, file_object)  # Write the file back to disk
5
  • You need to rewind file_object before writing, and truncate it after.
    – Barmar
    Commented May 14, 2021 at 15:18
  • 2
    You shouldn't modify a list while iterating over it. See stackoverflow.com/questions/6260089/…
    – Barmar
    Commented May 14, 2021 at 15:18
  • @Barmar good points, thanks, will fix..
    – Aaron F
    Commented May 14, 2021 at 15:58
  • @Barmar hopefully that's better now :-)
    – Aaron F
    Commented May 14, 2021 at 16:04
  • 1
    thanks, anonymous editor, i didn't know you could specify the language after the ```
    – Aaron F
    Commented May 14, 2021 at 17:34
0

Here's how you could do it with zq.

zq -f json '{...this, list: (over list | name != "APP1")}' input.json

zq is a command line tool for wrangling data. It uses the Zed language to manipulate streams of values.

0

As shown by James Kerr and also by Aaron F, but using jq rather than zq or Python. The operation sets the .list array to the elements of the original array that don't have .name equal to APP1.

$ jq '.list |= map(select(.name != "APP1"))' file
{
  "property1": true,
  "list": [
    {
      "id": 2,
      "name": "APP2"
    }
  ],
  "property2": false
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .