【问题标题】:convert pcregrep command in awk or sed在 awk 或 sed 中转换 pcregrep 命令
【发布时间】:2014-09-08 13:43:30
【问题描述】:

我有一个多行匹配的 pcregrep 命令,我想将它转换为 awk 或 sed 命令,因为我需要它在 pcregrep 不可用的机器上 (OS X)。

原始命令:

ifconfig -a | pcregrep -M '^[a-z].*\n(\t[^\n]+\n)+\t[^\n]+baseTX' | grep -oE "^([a-z]+[^:]+)"

它输出包含字符串“baseTX”的接口名称(我发现的唯一方法可以可靠地找出 MacBook 上的以太网接口名称)。在我的例子中,“en4”。

输入文本如下所示:

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    options=3<RXCSUM,TXCSUM>
    inet6 ::1 prefixlen 128 
    inet 127.0.0.1 netmask 0xff000000 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
    nd6 options=1<PERFORMNUD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    ether xx:xx:xx:xx:xx:xx 
    inet6 xxxx::xxxx:xxxx:xxxx:xxx%en0 prefixlen 64 scopeid 0x4 
    inet 10.xxx.xxx.xx netmask 0xffffff00 broadcast 10.xxx.xxx.255
    inet6 xxxx:xxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx prefixlen 128 
    nd6 options=1<PERFORMNUD>
    media: autoselect
    status: active
en5: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=60<TSO4,TSO6>
    ether xx:xx:xx:xx:xx:xx 
    media: autoselect <full-duplex>
    status: inactive
en6: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
    options=60<TSO4,TSO6>
    ether xx:xx:xx:xx:xx:xx 
    media: autoselect <full-duplex>
    status: inactive
en4: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=4<VLAN_MTU>
    ether xx:xx:xx:xx:xx:xx 
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx%en4 prefixlen 64 scopeid 0x7 
    inet XX.XXX.XXX.XX netmask 0xffffff00 broadcast XX.XXX.XXX.XXX
    inet6 xxxx:xxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx prefixlen 128 
    nd6 options=1<PERFORMNUD>
    media: autoselect (100baseTX <full-duplex>)
    status: active
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=63<RXCSUM,TXCSUM,TSO4,TSO6>
    ether xx:xx:xx:xx:xx:xx 
    Configuration:
        id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
        maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
        root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
        ipfilter disabled flags 0x2
    member: en5 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 5 priority 0 path cost 0
    member: en6 flags=3<LEARNING,DISCOVER>
            ifmaxaddr 0 port 6 priority 0 path cost 0
    nd6 options=1<PERFORMNUD>
    media: <unknown type>
    status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
    ether xx:xx:xx:xx:xx:xx 
    media: autoselect
    status: inactive

如何使用 awk 或 sed 获取“en4”?我试了一个小时,但我只是不擅长 sed 和 awk。

【问题讨论】:

  • 你有ip 命令吗? ip addr show 输出什么?
  • sed 只是单行简单替换的正确工具。一旦你开始谈论任何涉及选择或以其他方式在多行上操作的事情,你就应该使用 awk。
  • 我没有 ip 命令。感谢 Ed 的推荐,我会记住这一点的。

标签: awk sed multiline pcregrep


【解决方案1】:

假设间距是一致的(前导空格仅在非标题行上)这应该有效:

awk -F: '/^[[:alpha:]]/ {iface=$1; next} /baseTX/ {print iface; exit}'

【讨论】:

  • 太棒了。我很接近,但我试图用 awk 制作太复杂的东西,最后它非常简单。简单很难;)
  • 简单肯定很难。这就是为什么我最喜欢的正则表达式规则(但几乎适用于所有地方)是“不要尝试匹配比你关心的更多”。
【解决方案2】:

perl:

perl -0777 -nE 'say map {/^\w+/ && $&} grep {/baseTX/} split /^(?=\w+:)/m'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 2014-08-22
    相关资源
    最近更新 更多