Print only a part of a match with grep
<p>I'm interested whether I could use a single grep command for the following situation.</p>

<p>I have a dhcpd.conf file in which DHCP hosts are defined. Given the hostname, I need to find its MAC address in the dhcpd.conf file. I need to use it to disable its PXE boot config, but that's not part of this question.</p>

<p>The file's syntax is uniform, but I still want to make it a little fool-proof. Here is how the hosts are defined:</p>

<pre><code>    host client1 { hardware ethernet 12:23:34:56:78:89; fixed-address 192.168.1.11; filename "pxelinux.0"; }
    host client2 { hardware ethernet 23:34:45:56:67:78; fixed-address 192.168.1.12; filename "pxelinux.0"; }
    host client3 { hardware ethernet AB:CD:EF:01:23:45; fixed-address 192.168.1.13; filename "pxelinux.0"; }
    host client4 { hardware ethernet C1:CA:88:FA:F4:90; fixed-address 192.168.1.14; filename "pxelinux.0"; }
</code></pre>

<p>We assume that all configurations take only one line, even though the dhcpd.conf syntax would allow to break options to several lines. We assume that the order of options may differ, however.</p>

<p>I came up with the following grep command:</p>

<pre><code>grep -o "^[^#]*host.*${DHCP_HOSTNAME}.*hardware ethernet.*..:..:..:..:..:..;" /etc/dhcp/dhcpd-hosts.conf
</code></pre>

<p>It is supposed to ignore lines those are commented, allow arbitrary whitespace between tokens, and match until the end of the MAC address.
When I run it, I get lines like this:</p>

<pre><code>host client1 { hardware ethernet 12:23:34:56:78:89;
</code></pre>

<p>This is great! But the point is that I only need a MAC address, without the preceding trash. Now I know that using another grep, or cut, or awk to cut only the MAC address from this output would be trivial. But I wonder, is there a way to use a single grep command to get the end result, without having to pipe this output into another filter? Obviously I can't leave out the beginning of the pattern, because I want to get a specific hostname, thus matching for "<code>..:..:..:..:..:..</code>" would give me all the MAC addresses.</p>

<p>Once again, I want a single command (not necessarily grep) which cuts out only the proper MAC address from the file. Thus I am not interested in any solutions those say "grep ... | grep ..." or "grep ... | cut ...", etc..</p>

<p>Of course, in practice, nothing bad happens if I use multiple filters and pipe them, I am just curious whether it is possible to solve with one filter.</p>

<p>I would assign the output to a variable.</p>