Populating multiple arrays with output from a loop.

huangapple go评论60阅读模式
英文:

Populating multiple arrays with output from a loop

问题

Here's the translated portion of your text:

如何将循环的结果存储在数组中?

给定以下的 Bash 脚本:

types=("active_power" "_voltage" "_current" "total_active_energy")

function retrieveSensors () {
curl
-H "Authorization: Bearer $token"
-H "Content-Type: application/json"
"$endpoint/states"
| jq '.[] | select(.entity_id | startswith("sensor.shelly"))'
| grep entity_id
| sed 's/"entity_id": "(.*)",/\1/'
}

for str in ${types[@]}; do
retrieveSensors | grep $str
done


我正在努力将输出(4 个传感器实体的列表)存储在 4 个数组中。我已尝试:

declare -a output

for str in "${types[@]}"; do
output+=$(retrieveSensors | grep $str)
done

var1="${output[0]}"
var2="${output[1]}"
var3="${output[2]}"
var4="${output[3]}"


...但没有成功。var1 到 var4 是空的。
我认为我可能错过了一个非常简单的技巧。任何帮助都将不胜感激!

编辑:

明确一下,当仅使用

for str in ${types[@]}; do
retrieveSensors | grep $str
done


该脚本在屏幕上正确打印出 4 个预期的传感器类型列表,如电压传感器、电流等。

来自 `$endpoint/states` 的 JSON 输出如下:

```json
{
  "entity_id": "sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy",
  "state": "50.53842",
  "attributes": {
    "state_class": "total_increasing",
    "unit_of_measurement": "kWh",
    "device_class": "energy",
    "friendly_name": "shellypro3em-c8f09e8968b0 phase c total active energy"
  },
  "last_changed": "2023-05-25T15:36:59.985247+00:00",
  "last_updated": "2023-05-25T15:36:59.985247+00:00",
  "context": {
    "id": "01H19RWRAHXP5P2ZCG85W8Y131",
    "parent_id": null,
    "user_id": null
  }
}

有数百个传感器,我需要对其进行筛选。

从这个超长的 JSON 列表中,我需要匹配以下条件的 entity_id

  • 以 "sensor.shelly" 开头
  • 在 types=("active_power" "_voltage" "_current" "total_active_energy") 中

我现在意识到我不需要将适当的 entity_id 过滤后存储在多个数组中 - 一个数组就足够了!👍


Is there anything else you would like to know or clarify in this context?

<details>
<summary>英文:</summary>

How to store results of loops in arrays?

Given the following bash script:

types=("active_power" "_voltage" "_current" "total_active_energy")

function retrieveSensors () {
curl
-H "Authorization: Bearer $token"
-H "Content-Type: application/json"
"$endpoint/states"
| jq '.[] | select(.entity_id | startswith("sensor.shelly"))'
| grep entity_id
| sed 's/"entity_id": "(.*)",/\1/'
}

for str in ${types[@]}; do
retrieveSensors | grep $str
done


I&#39;m struggling to get the output (4x lists of sensor entities) stored in 4x arrays. I have tried:

declare -a output

for str in "${types[@]}"; do
output+=$(retrieveSensors | grep $str)
done

var1="${output[0]}"
var2="${output[1]}"
var3="${output[2]}"
var4="${output[3]}"


...to no avail. var1..var4 are empty.
I assume there&#39;s a hella easy trick I&#39;m missing here. Asssistance would be greatly appreciated!


EDIT:


to be clear, when using only

for str in ${types[@]}; do
retrieveSensors | grep $str
done


The script correctly prints to screen the 4x expected lists of specified sensor types, voltage sensors, current, etc.


The JSON output from `$endpoint/states` for a given sensor is:

{
"entity_id": "sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy",
"state": "50.53842",
"attributes": {
"state_class": "total_increasing",
"unit_of_measurement": "kWh",
"device_class": "energy",
"friendly_name": "shellypro3em-c8f09e8968b0 phase c total active energy"
},
"last_changed": "2023-05-25T15:36:59.985247+00:00",
"last_updated": "2023-05-25T15:36:59.985247+00:00",
"context": {
"id": "01H19RWRAHXP5P2ZCG85W8Y131",
"parent_id": null,
"user_id": null
}
},


There are hundreds of sensors, which I need to filter.

From this crazy long JSON list, I need the `entity_id`s matching:

    startswith(&quot;sensor.shelly&quot;)

AND

    types=(&quot;active_power&quot; &quot;_voltage&quot; &quot;_current&quot; &quot;total_active_energy&quot;)

It has now occured to me that I do not need to store the filtered list of appropriate `entity_id`s in multiple arrays - a single array would do just fine! &#128077;



</details>


# 答案1
**得分**: 3

首先,让我们将这个问题分解成更小的部分。例如,在您的实际代码中,您可能会有:

```shell
retrieveSensors() {
  curl \
    -H "Authorization: Bearer $token" \
    -H "Content-Type: application/json" \
    "$endpoint/states"
}

但在这个示例中,我将使用以下代码:

retrieveSensors() {
  cat <<'EOF'
[
  {
    "entity_id": "sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy",
    "state": "50.53842",
    "attributes": {
      "state_class": "total_increasing",
      "unit_of_measurement": "kWh",
      "device_class": "energy",
      "friendly_name": "shellypro3em-c8f09e8968b0 phase c total active energy"
    },
    "last_changed": "2023-05-25T15:36:59.985247+00:00",
    "last_updated": "2023-05-25T15:36:59.985247+00:00",
    "context": {
      "id": "01H19RWRAHXP5P2ZCG85W8Y131",
      "parent_id": null,
      "user_id": null
    }
  }
]
EOF
}

在以上任意一个示例中,我们可以运行以下代码:

readarray -t matchingSensorIds < <(
  retrieveSensors | jq -r '
    .[]
    | .entity_id
    | select(
        test(
          "sensor.shelly.*(active_power|_voltage|_current|total_active_energy)"
        )
      )
  '
)

或者,对于与古老的4.0版本之前的bash兼容性:

IFS=$'\n' read -r -d '' -a matchingSensorIds < <(
  retrieveSensors | jq -r '
    .[]
    | .entity_id
    | select(
        test(
          "sensor.shelly.*(active_power|_voltage|_current|total_active_energy)"
        )
      )
  ' && printf '
IFS=$'\n' read -r -d '' -a matchingSensorIds < <(
  retrieveSensors | jq -r '
    .[]
    | .entity_id
    | select(
        test(
          "sensor.shelly.*(active_power|_voltage|_current|total_active_energy)"
        )
      )
  ' && printf '\0'
)
'
)

这将创建一个类似以下的数组:

$ declare -p matchingSensorIds
declare -a matchingSensorIds=("sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy")

其中仅包含以 sensor.shelly 开头并包含 active_power_voltage_currenttotal_active_energy 的传感器ID。

英文:

First, let's break this down into smaller pieces. For example, in your real code you might have:

retrieveSensors() {
  curl \
    -H &quot;Authorization: Bearer $token&quot; \
    -H &quot;Content-Type: application/json&quot; \
    &quot;$endpoint/states&quot;
}

but in this example, I'm instead going to use:

retrieveSensors() {
  cat &lt;&lt;&#39;EOF&#39;
[
  {
    &quot;entity_id&quot;: &quot;sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy&quot;,
    &quot;state&quot;: &quot;50.53842&quot;,
    &quot;attributes&quot;: {
      &quot;state_class&quot;: &quot;total_increasing&quot;,
      &quot;unit_of_measurement&quot;: &quot;kWh&quot;,
      &quot;device_class&quot;: &quot;energy&quot;,
      &quot;friendly_name&quot;: &quot;shellypro3em-c8f09e8968b0 phase c total active energy&quot;
    },
    &quot;last_changed&quot;: &quot;2023-05-25T15:36:59.985247+00:00&quot;,
    &quot;last_updated&quot;: &quot;2023-05-25T15:36:59.985247+00:00&quot;,
    &quot;context&quot;: {
      &quot;id&quot;: &quot;01H19RWRAHXP5P2ZCG85W8Y131&quot;,
      &quot;parent_id&quot;: null,
      &quot;user_id&quot;: null
    }
  }
]
EOF
}

Given one of the above, we can run:

readarray -t matchingSensorIds &lt; &lt;(
  retrieveSensors | jq -r &#39;
    .[]
    | .entity_id
    | select(
        test(
          &quot;sensor.shelly.*(active_power|_voltage|_current|total_active_energy)&quot;
        )
      )
  &#39;
)

...or, for compatibility with ancient pre-4.0 bash releases:

IFS=$&#39;\n&#39; read -r -d &#39;&#39; -a matchingSensorIds &lt; &lt;(
  retrieveSensors | jq -r &#39;
    .[]
    | .entity_id
    | select(
        test(
          &quot;sensor.shelly.*(active_power|_voltage|_current|total_active_energy)&quot;
        )
      )
  &#39; &amp;&amp; printf &#39;
IFS=$&#39;\n&#39; read -r -d &#39;&#39; -a matchingSensorIds &lt; &lt;(
retrieveSensors | jq -r &#39;
.[]
| .entity_id
| select(
test(
&quot;sensor.shelly.*(active_power|_voltage|_current|total_active_energy)&quot;
)
)
&#39; &amp;&amp; printf &#39;\0&#39;
)
&#39; )

...which will create an array like the following:

$ declare -p matchingSensorIds
declare -a matchingSensorIds=([0]=&quot;sensor.shellypro3em_c8f09e8968b0_phase_c_total_active_energy&quot;)

containing only those sensor ids that start with sensor.shelly and contain active_power, _voltage, _current, or total_active_energy.

huangapple
  • 本文由 发表于 2023年5月25日 22:46:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76333570.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定