在tcp的第一次匹配时提取子字符串,然后在格式化列表中提取子字符串

时间:2013-12-24 22:14:25

标签: bash

我想在tcp的第一个匹配项中提取子字符串,然后将此提取存储在我可以处理的列表中。

我的脚本如下所示:

#!/bin/bash
procs=$(netstat -tulpn | tr -s ' ' | cut -f 1,4 -d ' ');
当我回显procs变量时,

输出看起来像这样:

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

我会提前获取一个带有“$ protocol / $ port”字符串值的列表,如

tcp/4369
tcp/5984
etc 

2 个答案:

答案 0 :(得分:1)

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'匹配从tcp开始到结尾的第一行。
  • awk -F ' |:' '{ printf "%s/%s\n", $1, $NF }'将输入拆分为由空格或':'分隔的字段,产生协议名称($1)和行的最后一个字段($NF),然后合成printf声明的信息。

正如@rici指出的那样,在-p使用netstat是不必要的,因为你忽略了它添加的信息。

除了假设一定数量的标题行之外,他的解决方案在概念上更清晰,更通用。

如果您想避免对标题行数量或首先采用哪种协议进行假设(如上述方法),您可以尝试以下方法:

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 }'
  • egrep命令返回第4列的匹配行,如果它们以协议名称(小写字母后跟小写字母和数字的组合)开头,后跟2个数字列,列用空格分隔 - 这应该清除标题行。

要将此方法与@ rici的解决方案结合使用,请将egrep表达式替换为tail -n+3

答案 1 :(得分:1)

这是一种可能性,它依赖于netstat输出两个标题行(不理想,但它已经这样做了几十年所以它现在可能不会停止)。请注意,我从p调用中删除了netstat选项,因为您无论如何都丢弃了程序信息,所以没有必要这样做:

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