Search code examples
bashjq

jq: error Cannot index string with string "value"


Given:

MY_JSON=$(cat <<EOF
{
  "schema": "my.schema",
  "properties": [
    {
      "type": "new.data",
      "value": {
        "labels": {
          "ofasd.io/arch.amd64": "supported",
          "ofasd.io/arch.arm64": "supported",
          "ofasd.io/arch.ppc64le": "supported",
          "ofasd.io/arch.s390x": "unsupported"
        }
      }
    }
  ]
}
EOF
)

I'm trying to filter only "supported" architectures:

arches=$(echo "$MY_JSON" | tr -d '\000-\031' | jq -r '
.properties[] 
| select(.type == "new.data") 
| .value.labels 
| to_entries 
| map(select(.key | test("^ofasd\\.io/arch\\.") and .value == "supported")) 
| map(.key | sub("^ofasd\\.io/arch\\."; "")) 
| join("\n")')

Expected output:

amd64
arm64
ppc64le

Actual output:

jq: error (at <stdin>:0): Cannot index string with string "value"

Could someone please help me understand what I'm doing wrong? It seems like the issue is that ofasd.io/arch.* filtering is not working. When I run:

echo "$MY_JSON" | jq -r '
.properties[] 
| select(.type == "new.data") 
| .value.labels 
| to_entries 
| map(select(.key | test("^ofasd.io/arch\\.") and .value == "supported"))'

I get:

echo "$MY_JSON" | jq -r '' failed with status 5

Solution

  • In select(.key | test("^ofasd\\.io/arch\\.") and .value == "supported"), you dive into .key, make your test (which, btw, could be simplified to startswith("ofasd.io/arch.")), but then there's no .value (inside .key) anymore. Wrap it in parens to keep the context: select((.key | test("^ofasd\\.io/arch\\.")) and .value == "supported")

    Here's a simplified version

    .properties[]
    | select(.type == "new.data")
    | .value.labels
    | to_entries[]
    | select(.value == "supported").key
    | scan("^ofasd.io/arch.\\K.*")
    
    amd64
    arm64
    ppc64le
    

    Demo