Dado:
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
)
Estou tentando filtrar apenas arquiteturas "compatíveis":
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")')
Saída esperada:
amd64
arm64
ppc64le
Produção real:
jq: error (at <stdin>:0): Cannot index string with string "value"
Alguém poderia me ajudar a entender o que estou fazendo errado? Parece que o problema é que a filtragem ofasd.io/arch.* não está funcionando. Quando executo:
echo "$MY_JSON" | jq -r '
.properties[]
| select(.type == "new.data")
| .value.labels
| to_entries
| map(select(.key | test("^ofasd.io/arch\\.") and .value == "supported"))'
Eu entendo:
echo "$MY_JSON" | jq -r '' failed with status 5
Em
select(.key | test("^ofasd\\.io/arch\\.") and .value == "supported")
, você mergulha em.key
, faz seutest
(que, a propósito, poderia ser simplificado parastartswith("ofasd.io/arch.")
), mas então não há mais.value
(dentro de.key
). Envolva-o em parênteses para manter o contexto:select((.key | test("^ofasd\\.io/arch\\.")) and .value == "supported")
Aqui está uma versão simplificada
Demonstração
O operador de pipe (
|
) tem precedência maior do que você pensa e a condição emmap(select(...))
é avaliada de uma maneira diferente da que você deseja.Você pode corrigir isso colocando
.key | test("^ofasd\\.io/arch\\.")
parênteses.Em vez disso,
join("\n")
eu usaria o iterador de array (.[]
). Combinado com a opção de linha de comando-r
(saída bruta), ele produz a saída que você espera.Se você aplicar o iterador antes, depois de
to_entries
, não há necessidade demap()
mais nada:Você pode ver isso funcionando neste playground JQ .