I need to find all active network interfaces on new macOS. That means the following one-liner with pcregrep
will not work:
ifconfig | pcregrep -M -o '^[^\t:] (?=:([^\n]|\n\t)*status: active)'
because pcregrep
is no default install on macOS.
I tried to translate it into egrep
to no avail, because a positive lookahead is not possible, right?
So I tried with a one-liner in perl. But the following command is not working, because the switch -pe
is not gobbling up all lines together. I tried with -p0e
too.
ifconfig | perl -pe 'while (<>) {if (/^[^\t:] (?=:([^\n]|\n\t)*status: active)/){print "$1";};}'
If I search with a positive lookahead the same line, it is working; for example:
ifconfig | perl -pe 'while (<>) {if (/^([^\t:] )(?=:([^\n]|\n\t)*mtu 1380)/){print "$1";};}'
utun0
A typical output of ifconfig
:
en10: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=6467<RXCSUM,TXCSUM,VLAN_MTU,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
ether 00:e0:4c:68:01:20
inet6 fe80::1470:31b9:a01c:6f5e%en10 prefixlen 64 secured scopeid 0xd
inet 192.168.178.39 netmask 0xffffff00 broadcast 192.168.178.255
inet6 2003:ee:4f1a:ce00:864:f90c:9a11:6ad9 prefixlen 64 autoconf secured
inet6 2003:ee:4f1a:ce00:d89a:7e34:6dd4:1370 prefixlen 64 autoconf temporary
nd6 options=201<PERFORMNUD,DAD>
media: autoselect (1000baseT <full-duplex>)
status: active
The expected result would be:
en10
I am on macOS Monterey, zsh and perl 5.34
Thank you for your help
marek
CodePudding user response:
perl's -n and -p command-line switches add an implicit while (<>) {...} block around the -e code, and in addition -p prints the line at the end of each iteration. So you need to change the -p to -n and only print out the lines which match; and remove the extra and unneeded while loop. So something like
ifconfig | perl -ne 'print if /...../'
CodePudding user response:
You can use
perl -0777 -nE 'say "$&" while /^[^\n\r\t:] (?=:(?:.*\R\t)*status:\h active)/gm'
See the regex test.
Here, -0777
slurps the file so that a regex could match multiline text spans (the M
equivalent that exposes the newlines to the pattern in pcregrep), say "$&"
prints all matched substrings (the o
equivalent, also see g
flag).
I edited the [^\t:]
to match any one or more chars other than tabs, colons and also CR/LF chars. Also, I replaced ([^\n]|\n\t)*
into a more efficient (?:.*\R\t)*
that matches zero or more occurrences of any zero or more chars other than line break chars till the end of a line (.*
), then a line break sequence (\R
), and then a tab char (\t
).
Also, note the m
flag to make ^
anchor also match any line start position.
CodePudding user response:
Given that output of ifconfig
normally has a multiline block of text for each interface, separated by a blank line, it is convenient to read it in paragraphs (-00). Then the rest simplifies a lot
ifconfig -a | perl -00 -nE'say $1 if /^([^:] )\s*:.*?status:\s active/s'