1

I have a multiline matching pcregrep command that I'd like to convert into an awk or sed command, because I need it on a machine where pcregrep is not available (OS X).

Original command:

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

It output the name of the interface that contains the string “baseTX” (only method I found to reliably find out the name of the ethernet interface on a MacBook). In my case, “en4”.

The input text look like this:

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

How can I grap “en4” with awk or sed? I tried for one hour, but I am just bad at sed and awk.

KaZ
  • 13
  • 3
  • Do you have the `ip` command? What does `ip addr show` output? – Etan Reisner Sep 08 '14 at 13:49
  • sed is only the right tool for simple substitutions on single lines. As soon as you start talking about anything involving selecting or otherwise operating on multiple lines you should be using awk. – Ed Morton Sep 08 '14 at 14:03
  • I don't have the ip command. Thanks for the recommendation Ed, I will keep this in mind. – KaZ Sep 08 '14 at 14:22

2 Answers2

6

Assuming that spacing is consistent (leading spaces are only on non-header lines) this should work:

awk -F: '/^[[:alpha:]]/ {iface=$1; next} /baseTX/ {print iface; exit}'
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • fantastic. I was close but I tried to make too complex stuff with awk, it was very simple in the end. Simple is hard ;) – KaZ Sep 08 '14 at 14:21
  • Simple is definitely hard. That's why my favorite rule of regex (but applies almost everywhere) is "don't try to match more than you care about". – Etan Reisner Sep 08 '14 at 14:26
0

perl:

perl -0777 -nE 'say map {/^\w+/ && $&} grep {/baseTX/} split /^(?=\w+:)/m'
glenn jackman
  • 238,783
  • 38
  • 220
  • 352