The D Merged
The D Merged

Reputation: 680

Extract substring at first match of tcp and on to a formatted list

I want to extract a substring at the first match of tcp and on then store this extraction in a list that I can process.

My script looks like this:

#!/bin/bash
procs=$(netstat -tulpn | tr -s ' ' | cut -f 1,4 -d ' ');

output looks like this when i echo the procs variable:

Active (only Proto Local tcp 0.0.0.0:4369 tcp 127.0.0.1:5984 tcp 127.0.0.1:5954 tcp 0.0.0.0:33123 tcp6 :::10000 tcp6 :::9000 tcp6 :::5672 udp 0.0.0.0:68 udp 0.0.0.0:52382 udp 0.0.0.0:5353 udp6 :::43913 udp6 :::5353

I would prefare tp get a list with "$protocol/$port" string values like

tcp/4369
tcp/5984
etc 

Upvotes: 0

Views: 124

Answers (2)

mklement0
mklement0

Reputation: 439307

netstat -tuln 2>/dev/null | tr -s ' ' | cut -f 1,4 -d ' ' | \
 sed -En '/^tcp/,$ p' | \
 awk -F ' |:' '{ printf "%s/%s\n", $1, $NF }'
  • sed -En '/^tcp/,$p' matches from the first line starting with tcp through the end.
  • awk -F ' |:' '{ printf "%s/%s\n", $1, $NF }' splits the input into fields separated by either a space or ':', yielding the protocol name ($1) and the line's last field ($NF), then synthesizes the information with the printf statement.

As @rici points out, using -p with netstat is unnecessary here, because you're ignoring the information added by it.

Aside from assuming a fixed number of header rows, his solution is conceptually cleaner and more generic.

If you wanted to avoid making assumptions about the number of header rows or which protocol comes first (as in the above approach), you could try the following:

netstat -tuln | \
 egrep -o '^[a-z][a-z0-9]+\s+[0-9]+\s+[0-9]+\s+\S+' | \
 awk -F ' |:' '{ printf "%s/%s\n", $1, $NF }'
  • The egrep command returns matching lines up to the 4th column IF they start with a protocol name (lowercase letter followed by a combination of lowercase letters and digits), followed by 2 numerical columns, with columns separated by whitespace - this should weed out the header lines.

To combine this approach with @rici's solution, substitute above egrep expression for tail -n+3.

Upvotes: 1

rici
rici

Reputation: 241861

Here's one possibility, which counts on netstat outputting two header lines (not ideal, but it has done so for decades so it probably won't stop now). Note that I removed the p option from the netstat invocation since you're throwing away the program information anyway, so there is no point asking for it:

netstat -tuln | tail -n+3 | while read PROTO RECVQ SENDQ LOCAL REST; do
  printf '%s/%s\n' $PROTO ${LOCAL##*:}
done

Upvotes: 1

Related Questions