如何过滤掉具有特定 属性 的元素(或保留没有 属性 的元素)

How to filter out elements with a particular property (or keep elements without that property)

我正在处理 dcm2json 的输出,它将元数据从 DICOM 格式的医学成像数据转换为 JSON。此元数据的值主要是字符串、整数、浮点数等,但它也包括 base64 编码字符串形式的内联二进制值。我们不需要那些二进制文件,它们可能会变得非常大,所以我需要过滤掉所有具有 InlineBinary 属性 的元数据元素。以下是 dcm2json 的 JSON 输出的(非常简单的小)样本:

{
    "00080005": {
        "vr": "CS",
        "Value": ["ISO_IR 192"]
    },
    "00291010": {
        "vr": "OB",
        "InlineBinary": "Zm9vYmFyCg=="
    }
}

我想运行将其转换为:

{
    "00080005": {
        "vr": "CS",
        "Value": ["ISO_IR 192"]
    }
}

我尝试了一些不同的方法,但都不起作用,但最终还是使用了这个:

$ dcm2json file.dcm | jq '[to_entries | .[] | select(.value.Value)] | from_entries'

虽然我一直在玩它,因为我不喜欢在数组中嵌入该表达式(即 [to_entries ...])。我想出了一些更优雅的东西,但我完全不知道为什么它会这样工作:

jq 'to_entries | . - map(select(.value | has("InlineBinary") == true)) | from_entries' | less

令人困惑的是 has("InlineBinary") == true 位。我首先 运行 将其与 false 进行比较,因为我想要的是那些 没有 的元素 InlineBinary 属性。为什么它的工作看起来与我认为我要求的相反?鉴于我真的不明白那里的 . - map(...) 结构发生了什么(我完全从另一个 post 那里偷走了它,那里有人问了类似的问题),我并不惊讶它做了我不知道的事情不明白,但我想明白为什么会这样:)

我感到困惑的另一件事是 to_entries/from_entries/with_entriesmanual says about these:

with_entries(foo) is a shorthand for to_entries | map(foo) | from_entries

酷!那将是:

jq 'with_entries(map( . - map(select(.value | has("InlineBinary") == true))))'

但这不起作用:

$ cat 1.json | jq 'with_entries(map(. - map(select(.value | has("InlineBinary") == true))))'
jq: error (at <stdin>:848): Cannot iterate over string ("00080005")

鉴于此声明在功能上应该是等效的,我不确定为什么这行不通。

感谢您提供的任何信息!

选择 key-value 对时,with_entries 通常是首选工具:

with_entries( select(.value | has("InlineBinary") | not) )