Bash

在 bash 腳本中使用 jq 來獲取具有特定值模式的元素

  • June 27, 2022

我在 shell 腳本中呼叫 homebrew api,目的是在嘗試安裝之前獲取項目的應用程序名稱。幸運的是,api 在一個名為artifacts. 不幸的是,artifacts沒有更多的鍵來選擇一個元素。它可以是任意順序的對象和數組的混合。

Google Chrome 的範例數據片段:

{
  "name":[
     "Google Chrome"
  ],
  "artifacts":[
     [
        "Google Chrome.app"
     ]
  ]
}

但碼頭工人是一個不同的故事:

{
  "name":[
     "Docker"
  ],
  "artifacts":[
      {
        "trash":[
          "$(brew --prefix)/bin/docker-compose.backup",
          "$(brew --prefix)/bin/docker.backup"
        ]
     },
     [
        "docker.app"
     ]
  ]
}

所以我不能artifacts像這樣從我的shell腳本中獲取元素0。

artifacts=$(curl -s "https://formulae.brew.sh/api/cask/google-chrome.json" | jq -r '.artifacts[0][0]')

有沒有辦法使用 jq 在artifacts元素中搜尋以 *.app 結尾的模式的值?我能想出的最好的虛擬碼就是這個,但是我在嘗試引用 $element 時遇到了一些麻煩

# $cask is determined by a list the script loops through ('google-chrome' is one example)
for element in $(curl -s "https://formulae.brew.sh/api/cask/$cask.json" | jq -r '.artifacts'); do
   # if $element is an array and it's value ends with "*.app"
       # assign to a variable for later use
done

這是一個更複雜的 JSON 返回之一的jqplay 片段。您將看到一個數組,其中包含唯一值“docker.app”。這就是我想要的目標。

與muru類似的查詢,但artifacts如果數組中的任何條目以字元串結尾,則返回任何數組中的所有人工製品.app

.artifacts[] | select(type == "array" and any(endswith(".app")))[]

或者,

.artifacts[] | arrays | select(any(endswith(".app")))[]

因此,如果一個應用程序有一些人工製品thething.app 並且 someotherthing.quux在同一個數組中,那麼兩者都會被返回。

jq查詢適用於我的 JSON for Docker:

.artifacts[] | arrays[0] | select(endswith(".app"))

arrays過濾器從 的元素中選擇數組,artifacts然後我們可以在這些數組的第一個元素中查找以 結尾的元素.app

引用自:https://unix.stackexchange.com/questions/707668