5

I have the following geojson file:

{
    "type": "FeatureCollection",
    "features": [{
            "type": "Feature",
            "properties": {
                "LINE": "RED",
                "STATION": "Harvard"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [-71.118906072378209, 42.37402923068516]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "LINE": "RED",
                "STATION": "Ashmont"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [-71.063430144389983, 42.283883546225319]
            }
        }
    ]
}

I would like to append the second object within the "features" array to the end of it, creating 3 total objects. Using the below snippet errors out with "array ([{"type":"F...) and object ({"type":"Fe...) cannot be added". Is there a way to do this using jq without hardcoding the key:value pairs as seen here?

cat red_line_nodes.json | jq '.features |= . + .[length-1]' > red_line_nodes_2.json
3
  • What exactly are you wanting to add to the array? Commented Feb 26, 2018 at 7:16
  • I want to duplicate one of the existing objects and add it to the array. Previous answers I had found on SO only show how to add a new object by typing in the various keys and values; what I want to know is if its possible to add in a new object using a reference to the existing file. Commented Feb 26, 2018 at 7:35
  • @m.brocks: Removed the duplicate tag complying to your above comment Commented Feb 26, 2018 at 8:00

2 Answers 2

4

Short jq solution:

jq '.features |= . + [.[-1]]' red_line_nodes.json

The output:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "LINE": "RED",
        "STATION": "Harvard"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -71.11890607237821,
          42.37402923068516
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "LINE": "RED",
        "STATION": "Ashmont"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -71.06343014438998,
          42.28388354622532
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "LINE": "RED",
        "STATION": "Ashmont"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          -71.06343014438998,
          42.28388354622532
        ]
      }
    }
  ]
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks - exactly what I was trying to figure out!
2

For reference, an alternative to using |= . + ... is to use +=. In your case, however, you would have to write:

.features += [.features[-1]]

so it's no shorter.

3 Comments

but how come that it does work? In |= the "context" from left side of operator is array, thus you have to address that array on right side of operator using just . While here you have to use .features on both sides of += operator. What is the explanation of that?
@MartinMucha - (FOO += BAR) has the semantics of . as $in | (FOO += ($in|BAR))
thanks! Not that I actually understand that (which still makes me laugh, that I'd expect to be surprised less and less as I learn jq, not otherwise). Let me try to interpret that. 1. I save current context into variable. 2. since |+ is IIRC |= . +) I will update FOO reachable from current context by adding to it current context filtered by BAR. Ah, yes, great, that's exactly what you did here and it explains the difference. Ok, I think I understand it now. Thanks again. (keeping this text here,it help me understand it writing it, it might work equally for reading)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.