【问题标题】:Extract substring within a given string提取给定字符串中的子字符串
【发布时间】:2021-06-03 19:58:27
【问题描述】:

我已阅读并尝试使用 awk、sed 或 grep 从给定字符串中提取子字符串,但我无法使其正常工作或思考如何完成此操作。

下面的字符串描述了我的虚拟机配置:

config: diskSizeGb: 100 diskType: pd-standard imageType: COS_CONTAINERD machineType: e2-micro metadata: disable-legacy-endpoints: 'true' preemptible: true status: RUNNING version: 1.19.9

如果知道每个 VM 的值可能不同,我如何提取子字符串,例如“preemptible: true”或“status: RUNNING”?

谢谢!

【问题讨论】:

    标签: linux bash shell


    【解决方案1】:

    假设:

    • VM 配置名称/值对的顺序可能不同
    • 配置名称和值是没有嵌入空格的单个字符串
    • 每个配置名称前面(至少)一个空格,后面紧跟一个冒号 (:)
    • 冒号(:)和配置值之间可能有多个空格;我们希望在输出中保留这些空间

    使用sed 和捕获组的一个想法:

    # note: extra spaces placed between 'version:' and '1.19.9'
    
    cfg_string="config: diskSizeGb: 100 diskType: pd-standard imageType: COS_CONTAINERD machineType: e2-micro metadata: disable-legacy-endpoints: 'true' preemptible: true status: RUNNING version:   1.19.9"
    
    for config in preemptible status version
    do
            echo "++++++++++++++ ${config}"
            sed -nE "s/.* (${config}:[ ]*[^ ]*).*/\1/p" <<< "${cfg_string}"
    done
    

    sed详情:

    • -nE - 禁用输入的默认打印(我们将使用/p 显式打印我们的捕获组;启用Extended regex 支持
    • .* (${config}:[ ]*[^ ]*).* - 匹配可变数量的字符 (.*) + 一个空格 ( ) + ${config} + 一个冒号 (:) + 一个或多个空格 ([ ]*) + 后面的所有内容不是空格([^ ]*)+ 输入的其余部分(.*);括号标记捕获组的开始/结束(在这种情况下只有一个捕获组)
    • \1 - 参考捕获组 #1(即括号内的所有内容)
    • /p - 打印(捕获组)

    这会生成:

    ++++++++++++++ preemptible
    preemptible: true
    ++++++++++++++ status
    status: RUNNING
    ++++++++++++++ version
    version:   1.19.9                # extra spaces maintained
    

    注意事项:

    • 显然无效的配置名称(例如,statversions)将不会产生任何输出
    • sed 结果可以被捕获在一个变量中以供进一步测试/处理(将解决无效配置名称的问题)

    【讨论】:

    • 哇@markp-fuso,这正是我想要的,你的假设是正确的。它可以根据每个虚拟机更改订单。您是否有机会分解 sed 命令以便我了解每个部分的作用?
    • @CaioT 添加了一些关于sed的注释
    • 非常感谢。非常感谢!
    【解决方案2】:

    这里有一个可能的解决方案:

    #!/bin/bash
    
    data="config: diskSizeGb: 100 diskType: pd-standard imageType: COS_CONTAINERD machineType: e2-micro metadata: disable-legacy-endpoints: 'true' preemptible: true status: RUNNING version: 1.19.9"
    
    preemptible=$(echo ${data} | cut -d ' ' -f 14)
    echo "preemptible = ${preemptible}"
    
    status=$(echo ${data} | cut -d ' ' -f 16)
    echo "status = ${status}"
    

    【讨论】:

    • 您好安东尼奥,感谢您的意见。 14 和 16 的值是空格吗?有没有更可靠的方法来提取这些字符串?我问的原因是因为虚拟机的配置可能会有所不同,并且一个可以比数据变量中的其他配置有更多的空间。
    • tte cut 命令用空格分割字符串,所以值14代表第14个字段,因此可抢占
    • 请注意,echo ${data} 本身就是错误的。如果你有value: *,你将把* 替换为当前目录中的文件名列表。 总是引用你的扩展:echo "$data" -- 花括号是完全可选的,引号不是。
    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 2011-07-21
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多