我需要解析以下命令以使用 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
数组来获取结果。