用 bash 解析字符串的更好方法?

用 bash 解析字符串的更好方法?

我需要解析以下命令以使用 bash 脚本提取命名空间和接口名称。我通常使用 IFS 来执行此操作,但这对我来说似乎很乏味。有没有更好的方法在不设置 IFS 的情况下执行此操作?

    ovsdb-client dump Open_vSwitch  | grep nw-uplink    
    ffff-fff-ffff-ffff-fffffffff [ffff-fff-ffff-ffff-fffffffff] 10      "v1.1"    {id="ffff-fff-ffff-ffff-fffffffff"}     []              10       {timeout1="180", timeout2="3600", type="", connid2-val="", sat-enabled=no, namespace=default, nw-uplink="tap0", platform=kvm, timer="300", dest=localhost, dest-port="514"} "0.0.0-1-priv" []  {}         RedHatEnterpriseServer "6.6-Sanity"

答案1

一个丑陋的 Awk 咒语:

 awk 'BEGIN{RS=" "; FS="="} {gsub(/,|"/,"")} /namespace/ {name=$2}; /uplink/ {intf=$2} END {print name": "intf}' <(command)
 default: tap0

答案2

请记住,Unix shell 是命令解释器,为了方便将几行代码放在一起进行更复杂的操作,运动控制结构和变量。他们是不是编程语言。是的,shell 脚本无处不在,因为它们非常便携(某种形式的 shell 随处可用),并且允许利用 Unix 管道和(更重要的是)组合在一起的系统管理命令的强大功能。

如果您想做一些更微妙的操作,请使用脚本语言,例如 Python(大多数 Linux 发行版使用它来编写各种系统管理 GUI,因此它几乎在任何地方都可用)或 Perl。

答案3

您可以使用 Python 和正则表达式来做到这一点:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Copyright © 2016 Martin Ueding <[email protected]>
# Licensed under The MIT License

import sys
import re

def main():
    for line in sys.stdin:
        m1 = re.search(r'namespace=([^,]+)', line)
        if m1:
            print(m1.group(1))
        m2 = re.search(r'nw-uplink=([^,]+)', line)
        if m2:
            print(m2.group(1))


if __name__ == '__main__':
    main()

只需将输出通过管道传输到那里,您将得到包含命名空间和接口的两行。

或者,人们也可以尝试grep --only-matching(或-o)消除感兴趣的部分。

最后,我们还可以在 Bash 中使用=~(or ~=?) 执行正则表达式,然后使用$BASH_REMATCH数组来获取结果。

相关内容