1

While looking for a way to format 'ifconfig' output and display only the network interfaces names, I found a regular expression that worked like a charm for OS X.

ifconfig -a | sed -E 's/[[:space:]:].*//;/^$/d'

How can I breakdown this regular expression so I can understand it?

Biffen
  • 5,354
  • 5
  • 27
  • 32
koperandus
  • 33
  • 3
  • Use [RegEx101](https://regex101.com/). – Sebastian Simon Aug 14 '18 at 13:52
  • 1
    Only `[[:space:]:].*` and `^$` are regular expressions here. [Here](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) is a reference on Stack Overflow for regexes, and [here](http://www.grymoire.com/Unix/Sed.html) is a good place to start learning about sed. – Benjamin W. Aug 14 '18 at 13:58
  • Possible duplicate of [Reference - What does this regex mean?](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) – Biffen Aug 14 '18 at 14:30

3 Answers3

2

Here is the sed command

s/[[:space:]:].*//;/^$/d

There is a semicolon in the middle, so it's actually two commands:

s/[[:space:]:].*//
/^$/d

First command is a substitution. What to substitute? It's between the 1st 2 slashes.

[[:space:]:].*

Character class [] of any kind of whitespace or a colon, followed by zero or more * of any character .. This matches everything in a line after the first whitespace or colon.

Substitute with what? Between the 2nd two slashes: s/...//: Nothing. The matched strings are deleted from each line.

This leaves the interface names which start their lines, the other lines remain too, but they are empty, as they start with whitespace.

How to remove these empty lines? That's the second command:

/^$/d

Find empty lines that match regex with nothing between start of line ^ and end of line $. Then delete them with command d.

All that's left are the interface names.

SzG
  • 11,409
  • 4
  • 23
  • 37
0

Thanks Benjamin and Xufox for the resources. After taking a look, this is my conclusion:

s/[[:space:]:].*//;

[[:space:]:] this will search for spaces and/or : and begin the execution of the command, and this and anything that comes afterwards(hence the '.*') will be substituted by nothing (because the next thing is //, which in between should be what we would want to substitute for, which in this case is nothing.).

;

marks the end of the first command

and then we have

/^$/d

where ^$ means search for all empty spaces and d to delete them.


This is half wrong. Take a look at the other answer which gives you the complete and correct response! Thanks guys.

koperandus
  • 33
  • 3
0

This is more a sequence of commands than it is a regular expression, but I suppose breaking the sequence down may be instructive.

Read the manpage on ifconfig to find this

Optionally, the -a flag may be used instead of an interface name. This flag instructs ifconfig to display information about all interfaces in the system. The -d flag limits this to interfaces that are down, and -u limits this to interfaces that are up. When no arguments are given, -a is implied.

That's one part done. The pipe (|) sends what ifconfig would normally print to the standard output to the standard input of sed instead.

You're passing sed the option -E. Again, man sed is your friend and tells you that this option means

Interpret regular expressions as extended (modern) regular expressions rather than basic regular expressions (BRE's). The re_format(7) manual page fully describes both formats.

This isn't all you need though... The first string that you're giving sed lets it know which operation to perform.

Search the same manual for the word "substitute" to reach this paragraph:

[2addr]s/regular expression/replacement/flags

Substitute the replacement string for the first instance of the regular expression in the pattern space. Any character other than backslash or newline can be used instead of a slash to delimit the RE and the replacement. Within the RE and the replacement, the RE delimiter itself can be used as a literal character if it is preceded by a backslash.

Now we can run man 7 re_format to decode the first command s/[[:space:]:].*// which means "for each line passed to standard input, substitute the part matching the extended regular expression [[:space:]:].* with the empty string"

  • [[:space:]:] = match either a : or any character in the character class [:space:]
  • .* = match any character (.), zero or more times (*)

To understand the second command look for the [2addr]d part of the sed manual page.

[2addr]d

Delete the pattern space and start the next cycle.

Let's then look at the next command /^$/d which says "for each line passed to standard input, delete it if it corresponds to the extended regex ^$"

  • ^$ = a line that contains no characters between its start (^) and its end ($)

We've discussed how to start with man pages and follow the clues to "decode" commands you see in everyday life.