我想在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
答案 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