【问题标题】:return nvme list as array using jq and loop thru it使用 jq 将 nvme 列表作为数组返回并循环遍历它
【发布时间】:2022-01-10 04:05:15
【问题描述】:

这就是我获取所有 NVME 卷的方式:

all_nvme_volumes=$(sudo nvme list -o json | jq .Devices[].DevicePath)

输出是这样的:

"/dev/nvme0n1" "/dev/nvme1n1" "/dev/nvme2n1" "/dev/nvme3n1" "/dev/nvme4n1" "/dev/nvme6n1"

我如何循环通过它们单独处理它们?

我试过for r in "${all_nvme_volumes[@]}"; do echo "Device Name: $r"; done,但输出是Device Name: "/dev/nvme0n1" "/dev/nvme1n1" "/dev/nvme2n1" "/dev/nvme3n1" "/dev/nvme4n1" "/dev/nvme6n1" 这是一个字符串而不是数组的每个元素:

【问题讨论】:

  • 与jq 和--raw-output(或-r)选项一起使用。它打印原始字符串而不是 JSON 字符串(被引用),每个项目的末尾都有一个换行符。然后你可以直接使用你想要的for 循环。无需使用 Bash 数组。另外:nvme 本身是否不能提供原始(非 JSON)输出,从而更容易在 shell 中进行迭代?
  • 请显示sudo nvme list -o json 的输出,并将您想要的输出(无描述、无图像、无链接)添加到您的问题(无评论)的示例输入中。

标签: arrays bash jq


【解决方案1】:

使用来自jq 的空分隔原始输出中的mapfile 填充bash 数组:

#!/usr/bin/env bash
mapfile -d '' all_nvme_volumes < <(
  sudo nvme list --output-format=json |
  jq --join-output '.Devices[].DevicePath + "\u0000"'
)

【讨论】:

    【解决方案2】:

    bash

    #!/bin/bash
    IFS=$'\t' read -r -a all_nvme_volumes < <(
        sudo nvme list -o json | jq -r '[ .Devices[].DevicePath ] | @tsv'
    )
    

    注意: 设备路径不应被@tsv 转义,因此您不需要对这些值进行转义,但如果您将此技巧用于其他目的,您可以对printf -v value '%b' "$value"的值


    我如何循环通过它们单独处理它们?

    好吧,一旦你有了数组,你就可以循环遍历它的元素:

    for nvme_volume in "${all_nvme_volumes[@]}"
    do
        # process "$nvme_volume"
    done
    

    但是,如果您只需要循环通过 nvme 卷而不存储它们,那么您可以使用 @LéaGris null delimiter method 和 while 循环:

    #!/bin/bash
    while IFS='' read -r -d '' nvme_volume
    do
        # process "$nvme_volume"
    done < <(sudo nvme list -o json | jq -j '.Devices[].DevicePath + "\u0000"')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 2012-03-10
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      相关资源
      最近更新 更多