使用 shell 命令如何从命令中提取字段 (zdb)

using shell commands how to extract field from command (zdb)

我需要 expand/resize a ZFS 磁盘但是为此,我需要从 zdb 的输出中提取 children[0] guid,当前输出如下所示:

root@:/ # zdb
zroot:
    version: 5000
    name: 'zroot'
    state: 0
    txg: 448
    pool_guid: 14102710366601156377
    hostid: 1798585735
    hostname: ''
    com.delphix:has_per_vdev_zaps
    vdev_children: 1
    vdev_tree:
        type: 'root'
        id: 0
        guid: 14102710366601156377
        create_txg: 4
        children[0]:
            type: 'disk'
            id: 0
            guid: 12530249324826415927
            path: '/dev/gpt/disk0'
            whole_disk: 1
            metaslab_array: 38
            metaslab_shift: 24
            ashift: 12
            asize: 1066926080
            is_log: 0
            create_txg: 4
            com.delphix:vdev_zap_leaf: 36
            com.delphix:vdev_zap_top: 37
    features_for_read:
        com.delphix:hole_birth
        com.delphix:embedded_data

为了使这个过程自动化并将所有步骤放在一个 shell 脚本中,我想到了这个:

zdb | grep -A4 "children\[0" | grep guid | awk -F ": " '{print }'

哪个returns:

12530249324826415927 

将所有脚本放在一起看起来像这样:

#!/bin/sh

DISK=`gpart list | head -n 1 | awk -F ": " '{print }'`
GUID=`zdb | grep -A4 "children\[0" | grep guid | awk -F ": " '{print }'`

gpart recover ${DISK}
gpart resize -i 3 ${DISK}
zpool online -e zroot ${GUID}
zfs set readonly=off zroot/ROOT/default

这是有效的,但想知道是否有更好的方法来提取字段而无需过多管道,我在 [=35= 的原始 FreeBSD 设置上执行此操作] 是只读的,所以我无法安装 python、bash 等,我只能使用 /usr/bin 中的基本堆栈,如 cut、awk、sed 等

如果我能直接从像 zdb 这样的命令中获取值就好了,但由于还没有找到直接的方法,我需要做一些 shell 功夫。

有什么改进的技巧和建议吗?

您可以使用如下的独立 Awk

zdb | awk '/children\[0\]/{flag=1; next} flag && /guid:/{split([=10=],arr,":"); print arr[2]; flag=0}'

如果前导空格令人担忧想办法使用sub()函数删除它作为sub(/^[[:space:]]/,"",arr[2])作为

zdb | awk '/children\[0\]/{flag=1; next} flag && /guid:/{split([=11=],arr,":"); sub(/^[[:space:]]/,"",arr[2]); print arr[2]; flag=0}'

想法是识别模式 children[0],启用标志,下一个匹配 guid: 匹配 仅当设置标志时 。这避免了对带有 guid: 的行的处理被重复多次并跳过它们。当识别出第一个匹配项时,该标志将被重置。

永远不要使用反引号替换命令,使用更有效的方式 $(..)