【Shell牛客刷题系列】SHELL31 netstat练习3-输出每个IP的连接数

2023-11-05



该系列是基于牛客Shell题库,针对具体题目进行查漏补缺,学习相应的命令。

刷题链接:牛客题霸-Shell篇

该系列文章都放到专栏下,专栏链接为:《专栏:Shell》。欢迎关注专栏~

本文知识预告:

  • 本文复习了awkgrepsortuniq命令的相关用法,并且新学习了awk命令中的split()函数的用法;
  • 然后给出了四种题目的解决方案。


SHELL31 netstat练习3-输出每个IP的连接数

假设netstat命令运行的结果我们存储在nowcoder.txt里,格式如下:

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:6160            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 172.16.56.200:41856     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:49822     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:49674     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:42316     172.16.34.143:3306      ESTABLISHED
tcp        0      0 172.16.56.200:44076     172.16.240.74:6379      ESTABLISHED
tcp        0      0 172.16.56.200:49656     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:58248     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:50108     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41944     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:35548     100.100.32.118:80       TIME_WAIT
tcp        0      0 172.16.56.200:39024     100.100.45.106:443      TIME_WAIT
tcp        0      0 172.16.56.200:41788     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:58260     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:41812     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:41854     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:58252     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:49586     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41754     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:50466     120.55.222.235:80       TIME_WAIT
tcp        0      0 172.16.56.200:38514     100.100.142.5:80        TIME_WAIT
tcp        0      0 172.16.56.200:49832     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:52162     100.100.30.25:80        ESTABLISHED
tcp        0      0 172.16.56.200:50372     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:50306     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:49600     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41908     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:60292     100.100.142.1:80        TIME_WAIT
tcp        0      0 172.16.56.200:37650     100.100.54.133:80       TIME_WAIT
tcp        0      0 172.16.56.200:41938     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:49736     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41890     172.16.34.144:3306      ESTABLISHED
udp        0      0 127.0.0.1:323           0.0.0.0:*
udp        0      0 0.0.0.0:45881           0.0.0.0:*
udp        0      0 127.0.0.53:53           0.0.0.0:*
udp        0      0 172.16.56.200:68        0.0.0.0:*
udp6       0      0 ::1:323                 :::*
raw6       0      0 :::58                   :::*                    7

现在需要你输出每个IP的连接数,按照连接数降序排序。你的脚本应该输出

172.16.0.24 10
172.16.34.144 9
100.100.142.4 3
0.0.0.0 3
172.16.34.143 1
172.16.240.74 1
120.55.222.235 1
100.100.54.133 1
100.100.45.106 1
100.100.32.118 1
100.100.30.25 1
100.100.142.5 1
100.100.142.1 1

相关命令学习

awk:文本和数据进行处理的编程语言

awk命令来自于三位创始人”Alfred Aho,Peter Weinberger, Brian Kernighan “的姓氏缩写,其功能是用于对文本和数据进行处理的编程语言。使用awk命令可以让用户自定义函数或正则表达式对文本内容进行高效管理,与sedgrep并称为Linux系统中的文本三剑客。

语法格式awk 参数 文件

常用参数

参数 功能
-F 指定输入时用到的字段分隔符
-v 自定义变量
-f 从脚本中读取awk命令
-m val值设置内在限制

常用的awk内置变量

awk语法由一系列条件和动作组成,在花括号内可以有多个动作,多个动作之间用分号分隔,在多个条件和动作之间可以有若干空格,也可以没有。

变量名称 说明
FILENAME 当前输入文档的文件名
FNR 当前输入文档的当前行号,尤其当多个输入文档时有用
FS 设置字段分隔符,默认为空格或制表符
NF 当前记录(行)的字段(列)个数
NR 输入数据流的当前记录数(行号)
OFS 输出字段分隔符,默认为空格
ORS 输出记录分隔符,默认为换行符
RS 输入记录分隔符,默认为换行符

awk是一种处理文本文件的编程语言,文件的每行数据都被称为记录默认以空格或制表符为分隔符每条记录被分成若干字段(列)awk每次从文件中读取一条记录

例子:

  1. 仅显示指定文件中第1、2列的内容(默认以空格为间隔符):
lucky@DESKTOP-VQ8KID4:~/shell$ awk '{print $1,$2}' nowcoder.txt
#include <iostream>
using namespace
int main()
{
int a
int b
cout <<
return 0;
}
  1. 以冒号为间隔符,仅显示指定文件中第1列的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ awk -F : '{print $1,$2}' /etc/passwd
root x
daemon x
bin x
...
tcpdump x
sshd x
landscape x
pollinate x
lucky x

/etc/passwd文件中的内容由:分隔开。

  1. 以冒号为间隔符,显示系统中所有UID号码大于500的用户信息(第3列):
lucky@DESKTOP-VQ8KID4:~/shell$ awk -F : '$3>=500' /etc/passwd
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
lucky:x:1000:1000:,,,:/home/lucky:/bin/bash
  1. 仅显示指定文件中含有指定关键词main的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ awk '/main/{print}' nowcoder.txt
int main()
  1. 以冒号为间隔符,仅显示指定文件中最后一个字段的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ awk -F : '{print $NF}' /etc/passwd
/bin/bash
/usr/sbin/nologin
/usr/sbin/nologin
...
/usr/sbin/nologin
/bin/false
/bin/bash
  1. 输出行号,NR将所有文件的数据视为一个数据流,而FNR则是将多个文件的数据视为独立的若干个数据流,遇到新文件时行号从1开始重新递增。
lucky@DESKTOP-VQ8KID4:~$ awk '{print NR}' first.txt three.sh
1
2
3
lucky@DESKTOP-VQ8KID4:~$ awk '{print FNR}' first.txt three.sh
1
1
2

awk中的split()函数

官方解释:

The awk function split(s,a,sep) splits a string s into an awk array a using the delimiter sep.

也即是:使用分隔符sep分割字符串s,得到的结果存入数组a中。

注意下标从1开始。

lucky@LAPTOP-G2DIO3FV:~$ cat date
2022:06:06:23:59
lucky@LAPTOP-G2DIO3FV:~$ awk '{split($0, a, ":"); print a[1]}' date
2022
lucky@LAPTOP-G2DIO3FV:~$ awk '{split($0, a, ":"); print a[3]}' date
06
lucky@LAPTOP-G2DIO3FV:~$ awk '{split($0, a, ":"); print a[1], a[2], a[3], a[4], a[5]}' date
2022 06 06 23 59

grep:强大的文本搜索工具

grep来自于英文词组“global search regular expression and print out the line”的缩写,意思是用于全面搜索的正则表达式,并将结果输出。人们通常会将grep命令与正则表达式搭配使用,参数作为搜索过程中的补充或对输出结果的筛选,命令模式十分灵活。

与之容易混淆的是egrep命令和fgrep命令。如果把grep命令当作是标准搜索命令,那么egrep则是扩展搜索命令,等价于“grep -E”命令,支持扩展的正则表达式。而fgrep则是快速搜索命令,等价于“grep -F”命令,不支持正则表达式,直接按照字符串内容进行匹配。

语法格式: grep [参数] 文件

常用参数:

参数 功能
-i 忽略大小写
-c 只输出匹配行的数量
-l 只列出符合匹配的文件名,不列出具体的匹配行
-n 列出所有的匹配行,显示行号
-h 查询多文件时不显示文件名
-s 不显示不存在、没有匹配文本的错误信息
-v 显示不包含匹配文本的所有行
-w 匹配整词
-x 匹配整行
-r 递归搜索
-q 禁止输出任何结果,已退出状态表示搜索是否成功
-b 打印匹配行距文件头部的偏移量,以字节为单位
-o -b结合使用,打印匹配的词据文件头部的偏移量,以字节为单位
-F 匹配固定字符串的内容
-E 支持扩展的正则表达式
  1. 搜索某个文件中,包含某个关键词的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
  1. 搜索某个文件中,以某个关键词开头的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ grep ^root /etc/passwd
root:x:0:0:root:/root:/bin/bash
  1. 搜索多个文件中,包含某个关键词的内容:
root@DESKTOP-VQ8KID4:~# grep lucky /etc/passwd /etc/shadow
/etc/passwd:lucky:x:1000:1000:,,,:/home/lucky:/bin/bash
/etc/shadow:lucky:$6$SBxuPYFLSnBcfbHN$OkFFnnJCpf2P4OLOnnaWXMq.xbmgL3H5aRy4nkEkk/.8VHABaKDS6MdYm3UR3TpHZplAl5HVyffI8nbLlAAoh1:19256:0:99999:7:::
  1. 搜索多个文件中,包含某个关键词的内容,不显示文件名称:
root@DESKTOP-VQ8KID4:~# grep -h lucky /etc/passwd /etc/shadow
lucky:x:1000:1000:,,,:/home/lucky:/bin/bash
lucky:$6$SBxuPYFLSnBcfbHN$OkFFnnJCpf2P4OLOnnaWXMq.xbmgL3H5aRy4nkEkk/.8VHABaKDS6MdYm3UR3TpHZplAl5HVyffI8nbLlAAoh1:19256:0:99999:7:::
  1. 输出在某个文件中,包含某个关键词行的数量:
root@DESKTOP-VQ8KID4:~# grep -c root /etc/passwd /etc/shadow
/etc/passwd:1
/etc/shadow:1
  1. 搜索某个文件中,包含某个关键词位置的行号及内容:
lucky@DESKTOP-VQ8KID4:~/shell$ grep -n int nowcoder.txt
3:int main()
5:    int a = 10;
6:    int b = 100;
  1. 搜索某个文件中,不包含某个关键词的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ grep -v int nowcoder.txt
#include <iostream>
using namespace std;
{
    cout << "a + b:" << a + b << endl;
    return 0;
}
  1. 搜索当前工作目录中,包含某个关键词内容的文件,未找到则提示:
root@DESKTOP-VQ8KID4:/# grep -l root *
grep: bin: Is a directory
grep: boot: Is a directory
grep: dev: Is a directory
grep: etc: Is a directory
grep: home: Is a directory
init
grep: lib: Is a directory
grep: lib32: Is a directory
...
grep: tmp: Is a directory
grep: usr: Is a directory
grep: var: Is a directory
  1. 搜索当前工作目录中,包含某个关键词内容的文件,未找到不提示:
lucky@DESKTOP-VQ8KID4:~/shell$ grep -sl main *
nowcoder.txt
  1. 递归搜索,不仅搜索指定目录,还搜索其内子目录内是否有关键词文件:
root@DESKTOP-VQ8KID4:/# grep -srl root /etc
/etc/services
/etc/ltrace.conf
/etc/systemd/logind.conf
/etc/crontab
/etc/newt/palette.ubuntu
/etc/xattr.conf
/etc/apparmor.d/tunables/home
...
  1. 搜索某个文件中,精准匹配到某个关键词的内容(搜索词应与整行内容完全一样才会显示,有别于一般搜索):
lucky@DESKTOP-VQ8KID4:~/shell$ grep -x "return 0;" nowcoder.txt
lucky@DESKTOP-VQ8KID4:~/shell$ grep -x "    return 0;" nowcoder.txt
    return 0;
  1. 判断某个文件中,是否包含某个关键词,通过返回状态值输出结果(0为包含,1为不包含),方便在Shell脚本中判断和调用:
lucky@DESKTOP-VQ8KID4:~/shell$ grep -q return nowcoder.txt
lucky@DESKTOP-VQ8KID4:~/shell$ echo $?  # 包含
0

lucky@DESKTOP-VQ8KID4:~/shell$ grep -q returns nowcoder.txt
lucky@DESKTOP-VQ8KID4:~/shell$ echo $?  # 不包含
1
  1. 搜索某个文件中,空行的数量:
lucky@DESKTOP-VQ8KID4:~/shell$ grep -c ^$ nowcoder.txt
0

sort:对文件内容进行排序

sort命令的功能是对文件内容进行排序。有时文本中的内容顺序不正确,一行行地手动修改实在太麻烦了。此时使用sort命令就再合适不过了,它能够对文本内容进行再次排序。

语法格式:sort [参数] 文件

常用参数:

-b 忽略每行前面开始出的空格字符
-c 检查文件是否已经按照顺序排序
-d 除字母、数字及空格字符外,忽略其他字符
-f 将小写字母视为大写字母
-i 除040至176之间的ASCII字符外,忽略其他字符
-m 将几个排序号的文件进行合并
-M 将前面3个字母依照月份的缩写进行排序
-n 依照数值的大小排序
-o <输出文件> 将排序后的结果存入制定的文件
-r 以相反的顺序来排序
-t <分隔字符> 指定排序时所用的栏位分隔字符
-k 指定需要排序的栏位

参考实例

对指定的文件内容按照字母顺序进行排序:

lucky@DESKTOP-VQ8KID4:~$ cat fruits.txt
watermelon
apple
blackberry
fig
kiwi
lemon
grapefruit
pineapple
banana
orange
lucky@DESKTOP-VQ8KID4:~$ sort fruits.txt
apple
banana
blackberry
fig
grapefruit
kiwi
lemon
orange
pineapple
watermelon

对指定的文件内容按照数字大小进行排序:

lucky@DESKTOP-VQ8KID4:~$ cat num.txt
32
2
56
321
33
22
1
45
lucky@DESKTOP-VQ8KID4:~$ sort -n num.txt
1
2
22
32
33
45
56
321

以冒号:为间隔符,对指定的文件内容按照数字大小对第3列进行排序:

lucky@DESKTOP-VQ8KID4:~$ cat /etc/passwd | sort -t : -k 3 -n
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
lucky:x:1000:1000:,,,:/home/lucky:/bin/bash
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

uniq:去除文件中的重复内容行

uniq命令来自于英文单词unique的缩写,中文译为独特的、唯一的,其功能是用于去除文件中的重复内容行uniq命令能够去除掉文件中相邻的重复内容行,如果两端相同内容中间夹杂了其他文本行,则需要先使用sort命令进行排序后再去重复,这样保留下来的内容就都是唯一的了。

划重点:去除相邻重复内容行!

语法格式:uniq [参数] 文件

常用参数:

-c 打印每行在文本中重复出现的次数
-d 每个重复纪录只出现一次
-u 只显示没有重复的纪录

参考实例

  1. 对指定的文件进行去重操作:
lucky@DESKTOP-VQ8KID4:~$ cat test.txt
nowcoder
nowcoder
nowcoder
to
welcome
welcome
lucky@DESKTOP-VQ8KID4:~$ uniq test.txt
nowcoder
to
welcome
  1. 统计相同内容行在文件中重复出现的次数:
lucky@DESKTOP-VQ8KID4:~$ uniq -c test.txt
      3 nowcoder
      1 to
      2 welcome
  1. 仅显示指定文件中存在一模一样内容行的信息:
lucky@DESKTOP-VQ8KID4:~$ uniq -d test.txt
nowcoder
welcome
  1. 仅显示指定文件中没有存在一摸一样内容行的信息:
lucky@DESKTOP-VQ8KID4:~$ uniq -u test.txt
to

题目解决方案

方法一:grep+awk+sort

  1. 去除第一行:
lucky@LAPTOP-G2DIO3FV:~$ grep -v "Foreign Address" nowcoder.txt
tcp        0      0 0.0.0.0:6160            0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 172.16.56.200:41856     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:49822     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:49674     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:42316     172.16.34.143:3306      ESTABLISHED
tcp        0      0 172.16.56.200:44076     172.16.240.74:6379      ESTABLISHED
tcp        0      0 172.16.56.200:49656     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:58248     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:50108     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41944     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:35548     100.100.32.118:80       TIME_WAIT
tcp        0      0 172.16.56.200:39024     100.100.45.106:443      TIME_WAIT
tcp        0      0 172.16.56.200:41788     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:58260     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:41812     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:41854     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:58252     100.100.142.4:80        TIME_WAIT
tcp        0      0 172.16.56.200:49586     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41754     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:50466     120.55.222.235:80       TIME_WAIT
tcp        0      0 172.16.56.200:38514     100.100.142.5:80        TIME_WAIT
tcp        0      0 172.16.56.200:49832     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:52162     100.100.30.25:80        ESTABLISHED
tcp        0      0 172.16.56.200:50372     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:50306     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:49600     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41908     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:60292     100.100.142.1:80        TIME_WAIT
tcp        0      0 172.16.56.200:37650     100.100.54.133:80       TIME_WAIT
tcp        0      0 172.16.56.200:41938     172.16.34.144:3306      ESTABLISHED
tcp        0      0 172.16.56.200:49736     172.16.0.24:3306        ESTABLISHED
tcp        0      0 172.16.56.200:41890     172.16.34.144:3306      ESTABLISHED
udp        0      0 127.0.0.1:323           0.0.0.0:*
udp        0      0 0.0.0.0:45881           0.0.0.0:*
udp        0      0 127.0.0.53:53           0.0.0.0:*
udp        0      0 172.16.56.200:68        0.0.0.0:*
udp6       0      0 ::1:323                 :::*
raw6       0      0 :::58                   :::*                    7
  1. 筛选tcp,提出第五列的IP地址,利用:作为分隔符,利用数组进行计数:
lucky@LAPTOP-G2DIO3FV:~$ grep -v "Foreign Address" nowcoder.txt | awk '$1~/tcp/{print $5}' | awk -F ":" '{arr[$1]+=1}END{for(k in arr)print(k,arr[k])}'
100.100.32.118 1
172.16.240.74 1
172.16.0.24 10
172.16.34.143 1
100.100.45.106 1
172.16.34.144 9
100.100.142.1 1
0.0.0.0 3
100.100.142.4 3
100.100.54.133 1
100.100.142.5 1
100.100.30.25 1
120.55.222.235 1
  1. 最后按照计数排序即可:
lucky@LAPTOP-G2DIO3FV:~$ grep -v "Foreign Address" nowcoder.txt | awk '$1~/tcp/{print $5}' | awk -F ":" '{arr[$1]+=1}END{for(k in arr)print(k,arr[k])}' | sort -nrk2
172.16.0.24 10
172.16.34.144 9
100.100.142.4 3
0.0.0.0 3
172.16.34.143 1
172.16.240.74 1
120.55.222.235 1
100.100.54.133 1
100.100.45.106 1
100.100.32.118 1
100.100.30.25 1
100.100.142.5 1
100.100.142.1 1

所以,最终的代码为:

grep -v "Foreign Address" nowcoder.txt | awk '$1~/tcp/{print $5}' | awk -F ":" '{
	arr[$1]+=1
}END{
	for(k in arr)
		print(k,arr[k])
}' | sort -nrk2

方法二:awk+split()+sort

该方法中直接使用split()函数,可以略去一些步骤,比如对于第一行的处理就不再需要了。

awk '{
    if ($1 == "tcp") {
        split($5, a, ":")
        t[a[1]]++
    }
} END {
    for (i in t){
        print i, t[i]
    }
}' nowcoder.txt | sort -nrk2

方法三:awk+sort

其实要解决这道题,我们要做的有两点:

  1. 提取出IP地址,包括筛选TCP
  2. 对IP地址计数

其实,关键之处就在于第一步。这个方法其实相较于前两个方法更简单。我们先给出完整代码:

awk -F "[ :]+" '/tcp/{
	a[$6]++
}END{
	for(i in a)
		print i,a[i]
}' nowcoder.txt | sort -nrk2

这里有一个比较陌生的东东,也就是"[ :]+"。其实这个是正则表达式,+表示一个或多个,这里就表示一个或多个空格或冒号

来看看下面的示例,就能清晰的知道是怎么分割的了。(注意对比原来的内容)

lucky@LAPTOP-G2DIO3FV:~$ awk -F '[ :]+' '/tcp/{print $1"---"$2"---"$3"---"$4"---"$5"---"$6}' no
wcoder.txt
tcp---0---0---0.0.0.0---6160---0.0.0.0
tcp---0---0---127.0.0.53---53---0.0.0.0
tcp---0---0---0.0.0.0---22---0.0.0.0
tcp---0---0---172.16.56.200---41856---172.16.34.144
tcp---0---0---172.16.56.200---49822---172.16.0.24
tcp---0---0---172.16.56.200---49674---172.16.0.24
tcp---0---0---172.16.56.200---42316---172.16.34.143
tcp---0---0---172.16.56.200---44076---172.16.240.74
tcp---0---0---172.16.56.200---49656---172.16.0.24
tcp---0---0---172.16.56.200---58248---100.100.142.4
tcp---0---0---172.16.56.200---50108---172.16.0.24
tcp---0---0---172.16.56.200---41944---172.16.34.144
tcp---0---0---172.16.56.200---35548---100.100.32.118
tcp---0---0---172.16.56.200---39024---100.100.45.106
tcp---0---0---172.16.56.200---41788---172.16.34.144
tcp---0---0---172.16.56.200---58260---100.100.142.4
tcp---0---0---172.16.56.200---41812---172.16.34.144
tcp---0---0---172.16.56.200---41854---172.16.34.144
tcp---0---0---172.16.56.200---58252---100.100.142.4
tcp---0---0---172.16.56.200---49586---172.16.0.24
tcp---0---0---172.16.56.200---41754---172.16.34.144
tcp---0---0---172.16.56.200---50466---120.55.222.235
tcp---0---0---172.16.56.200---38514---100.100.142.5
tcp---0---0---172.16.56.200---49832---172.16.0.24
tcp---0---0---172.16.56.200---52162---100.100.30.25
tcp---0---0---172.16.56.200---50372---172.16.0.24
tcp---0---0---172.16.56.200---50306---172.16.0.24
tcp---0---0---172.16.56.200---49600---172.16.0.24
tcp---0---0---172.16.56.200---41908---172.16.34.144
tcp---0---0---172.16.56.200---60292---100.100.142.1
tcp---0---0---172.16.56.200---37650---100.100.54.133
tcp---0---0---172.16.56.200---41938---172.16.34.144
tcp---0---0---172.16.56.200---49736---172.16.0.24
tcp---0---0---172.16.56.200---41890---172.16.34.144

方法四:awk+sort+uniq

思路继续打开…方法三虽然只需要两步,代码上很简单,但又不一定想得到是吧?

咱用上之前惯用套路…awk+sort+uniq+sort组合,解决这个问题就很简单了~

来,简单讲解一下步骤:

  1. :作为分隔符,提取出第二列,同时筛选出tcp
lucky@LAPTOP-G2DIO3FV:~$ awk -F ':' '/tcp/{print $2}' nowcoder.txt
6160            0.0.0.0
53           0.0.0.0
22              0.0.0.0
41856     172.16.34.144
49822     172.16.0.24
49674     172.16.0.24
42316     172.16.34.143
44076     172.16.240.74
49656     172.16.0.24
58248     100.100.142.4
50108     172.16.0.24
41944     172.16.34.144
35548     100.100.32.118
39024     100.100.45.106
41788     172.16.34.144
58260     100.100.142.4
41812     172.16.34.144
41854     172.16.34.144
58252     100.100.142.4
49586     172.16.0.24
41754     172.16.34.144
50466     120.55.222.235
38514     100.100.142.5
49832     172.16.0.24
52162     100.100.30.25
50372     172.16.0.24
50306     172.16.0.24
49600     172.16.0.24
41908     172.16.34.144
60292     100.100.142.1
37650     100.100.54.133
41938     172.16.34.144
49736     172.16.0.24
41890     172.16.34.144
  1. 以空格为分隔符,提取出第二列(awk命令默认的分隔符就是空格,所以不需要指定分隔符),也即是我们需要的IP地址
lucky@LAPTOP-G2DIO3FV:~$ awk -F ':' '/tcp/{print $2}' nowcoder.txt | awk '{print $2}'
0.0.0.0
0.0.0.0
0.0.0.0
172.16.34.144
172.16.0.24
172.16.0.24
172.16.34.143
172.16.240.74
172.16.0.24
100.100.142.4
172.16.0.24
172.16.34.144
100.100.32.118
100.100.45.106
172.16.34.144
100.100.142.4
172.16.34.144
172.16.34.144
100.100.142.4
172.16.0.24
172.16.34.144
120.55.222.235
100.100.142.5
172.16.0.24
100.100.30.25
172.16.0.24
172.16.0.24
172.16.0.24
172.16.34.144
100.100.142.1
100.100.54.133
172.16.34.144
172.16.0.24
172.16.34.144

看出来这两步在干嘛了吗?事实上,这两步就是方法三里面的"[ :]+"的效果!!!

  1. 后面的步骤就很简单了,先排序,再降重,这是前面的题都提到过的
lucky@LAPTOP-G2DIO3FV:~$ awk -F ':' '/tcp/{print $2}' nowcoder.txt | awk '{print $2}' | sort | uniq -c
      3 0.0.0.0
      1 100.100.142.1
      3 100.100.142.4
      1 100.100.142.5
      1 100.100.30.25
      1 100.100.32.118
      1 100.100.45.106
      1 100.100.54.133
      1 120.55.222.235
     10 172.16.0.24
      1 172.16.240.74
      1 172.16.34.143
      9 172.16.34.144
  1. 继续,注意看题目要求哈,计数要排在第二列,所以用awk交换一下顺序即可
lucky@LAPTOP-G2DIO3FV:~$ awk -F ':' '/tcp/{print $2}' nowcoder.txt | awk '{print $2}' | sort | uniq -c | awk '{print $2, $1}'
0.0.0.0 3
100.100.142.1 1
100.100.142.4 3
100.100.142.5 1
100.100.30.25 1
100.100.32.118 1
100.100.45.106 1
100.100.54.133 1
120.55.222.235 1
172.16.0.24 10
172.16.240.74 1
172.16.34.143 1
172.16.34.144 9
  1. 最后一步,排序即可
lucky@LAPTOP-G2DIO3FV:~$ awk -F ':' '/tcp/{print $2}' nowcoder.txt | awk '{print $2}' | sort | uniq -c | awk '{print $2, $1}' | sort -nrk2
172.16.0.24 10
172.16.34.144 9
100.100.142.4 3
0.0.0.0 3
172.16.34.143 1
172.16.240.74 1
120.55.222.235 1
100.100.54.133 1
100.100.45.106 1
100.100.32.118 1
100.100.30.25 1
100.100.142.5 1
100.100.142.1 1

故,最终代码如下:(做了一定的缩进,方便阅读)

awk -F ':' '/tcp/{
	print $2
}' nowcoder.txt | awk '{
	print $2
}' | sort | uniq -c | awk '{
	print $2, $1
}' | sort -nrk2

这个方法步骤很多,却是最简单的,套路和前面的题差不多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Shell牛客刷题系列】SHELL31 netstat练习3-输出每个IP的连接数 的相关文章

  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • 使用 awk 打印一列,添加逗号

    我有一个文件 我想从中检索第一列 并在每个值之间添加逗号 Example AAAA 12345 xccvbn BBBB 43431 fkodks CCCC 51234 plafad 获得 AAAA BBBB CCCC 我决定使用 awk 所
  • bash 将输出重定向到文件,但结果不完整

    重定向命令输出的问题已经被问过很多次了 但是我有一个奇怪的行为 我使用的是 bash shell debian 版本 4 3 30 1 release 并尝试将输出重定向到文件 但并非所有内容都记录在文件中 我尝试运行的 bin 文件是 l
  • MySQL 与 PHP 的连接无法正常工作

    这是我的情况 我正在尝试使用 Apache 服务器上的 PHP 文件连接到 MySQL 数据库 现在 当我从终端运行 PHP 时 我的 PHP 可以连接到 MySQL 数据库 使用 php f file php 但是当我从网页执行它时 它只
  • Python glob,操作系统,相对路径,将文件名放入列表中[重复]

    这个问题在这里已经有答案了 我正在尝试创建一个目录中所有文件的列表 其中文件名以 root 结尾 在阅读了论坛中的一些文章后 我尝试使用 glob 和 os listdir 的基本策略 但我都遇到了麻烦 首先 当我使用 import glo
  • 链接错误:命令行中缺少 DSO

    我对 Linux 使用 Ubuntu 14 04 LTS 64 位 相当陌生 来自 Windows 并且正在尝试移植我现有的 CUDA 项目 当通过链接时 usr local cuda bin nvcc arch compute 30 co
  • 如何使用 git hook pre-merge-commit 获取原始合并分支名称

    我正在尝试使用新的 git hook pre merge commit 创建一个特定的脚本 但它没有参数 有什么解决方法可以让我获得正在合并的分支的名称吗 例子 在分支 myBranch 上 我调用 git merge testingBra
  • 如何使用 Bash 编写二进制文件?

    我的问题是我需要创建一个包含以下确切字节的文件 48 00 49 00 我不能使用C perl 其他脚本语言 目标是嵌入式设备 我使用 awk 尝试过 在桌面上它确实有效 awk BEGIN printf c c c c 48 00 49
  • unix 下日期字段排序

    我有包含数十万条记录的文本文件 其中一个字段是日期字段 有没有办法根据日期字段对文件进行排序 09 APR 12 04 08 43 632279000 AM 19 MAR 12 03 53 38 189606000 PM 19 MAR 12
  • VBA Shell 并等待退出代码

    我正在打包一个办公应用程序 VBA 它调用 C 控制台应用程序来执行应用程序 大型模拟程序 的一些繁重工作 我希望能够让 VBA 应用程序等待控制台应用程序完成并从控制台应用程序检索退出代码 我已经能够做到前者 但尚未能够从应用程序中检索退
  • Ubuntu Python shebang 线不工作

    无法让 shebang 线在 Ubuntu 中为 python 脚本工作 我每次只收到命令未找到错误 test py usr bin env python print Ran which python usr bin python 在 sh
  • 如何在线程创建和退出时调用函数?

    include
  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • 关键字“if”如何测试一个值是真还是假?

    在 bash 脚本中 if 1 then echo Yes else echo No fi Output Yes 它表示 1 被视为真值 但在代码中 word Linux letter nuxi if echo word grep q le
  • ssh 连接超时

    我无法在 git 中 ssh 到 github bitbucket 或 gitlab 我通常会收到以下错误消息 如何避免它 输出 ssh T email protected cdn cgi l email protection i ssh
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • 比较两个文件的单列

    我有两个文件 每个文件都有两列 并用空格分隔 我想找到两个文件中第 2 列不相同的行 并将它们输出到第三个文件 file A 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2 BBBBBBBBBBBBBBBBBBBBBB
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • shell中如何分割字符串

    我有一个变量作为 string ABC400p2q4 我怎样才能分开ABC400 and p2q4 我需要将它分成两个变量 结果我得到 echo var1 ABC400 echo var2 p2q4 可以用任何字母字符代替 ABC 可以用任
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu

随机推荐

  • GC0063-51单片机手持可充电VL53L01激光测距离测量报警倒车雷达防撞报警视力保护

    实践制作DIY GC0063 51单片机手持激光测距离测量 一 功能说明 基于51单片机设计 51单片机手持激光测距离测量 二 功能介绍 STC89C52单片机 lcd1602 VL53L01激光测距 锂电池充电电路 18650锂电池 继电
  • 基于时序数据处理的分布式光伏功率预测系统

    摘要 目的 使用高质量的历史数据预测未来光伏发电功率 对高效利用太阳能可再生能源 补充电网供电能力和推进节能减碳具有重要意义 方法 由于光伏时序数据质量参差不齐 本文提出了面向光伏时序数据的缺失值与异常值处理算法 并基于此搭建了分布式光伏功
  • 医学自然语言处理(NLP)相关论文汇总之 EMNLP 2021

    医学自然语言处理 NLP 相关论文汇总之 EMNLP 2021 写在前面 EMNLP2021前段时间已经放榜 一直没时间整理 最近抽时间整理了一下该会议在医疗自然语言处理方向上的相关论文 放在这里 希望对大家有一定的帮助吧 还会继续更新 大
  • Unity3D获得Android和iOS设备的唯一标识

    前言 android为mac地址 ios为advertisingIdentifier 函数都比较简单 网上也搜得到 我也就不多说了 主要是对于我们没做过安卓和IOS开发的人来说 整合进工程有各种的问题 我也就直接上网盘了点击打开链接 代码包
  • 【ant design vue】图片上传(一)

    官网是这样的 action 官网说不管是否使用都不能空着 但是实际上 在我的项目中是没有使用到的 我们是动态上传到后端 然后后端返回一个图片地址给我们显示在前台 代码如下 accept 是限制图片上传类型 customRequest 是自定
  • android edittext 数字正则,一个带有正则匹配的EditText

    先上效果 说明 图中的EditText能够在失去焦点后验证输入框中的文本是否与正则表达式匹配 这里我设置的是5位整数 d 5 当输入110时 不匹配 边框变红并抖动 文本清除 gif中白色文本是因为录制的问题 实际文本已清除 输入12306
  • windows10 powershell窗口输出卡住(看这篇就够了)

    问题原因 cmd窗口开启了快速编辑模式 当点击窗口时运行的进程会被暂停直至点击回车按钮 解决方案 取消勾选快速编辑模式 1 第一步 右键标题栏 选择 属性 第二步 选择 编辑选项 区域 取消 快速编辑模式 的选项 如图所示
  • Linux安装mysql5.7.26 --(傻瓜版3分钟搞定)

    前言 在这之前的一天时间里 我全网搜mysql 的各种安装方式 还有版本不同带来的问题 会发现在 Mac 或者 在linux上安装5 7 一下版本时 出现的问题会少很多 尤其是 拿着 dmg文件在Mac 安装 就是1分钟的事 但是在linu
  • Qt 中实现阴影窗口

    阴影窗口的实现方法一般有三种 方法一是 在窗口的构造函数中设置窗口的属性为 setAttribute Qt WA TranslucentBackground 从而保证窗口不被绘制的部分透明化 接着重写绘制函数paintEvent 其代码示例
  • 变量、作用域与内存

    目录 原始值与引用值 动态属性 复制值 传递参数 确定类型 执行上下文与作用域 作用域链增强 变量声明 1 使用var 的函数作用域声明 2 使用let 的块级作用域声明 3 使用const 的常量声明 标识符查找 垃圾回收 标记清理 最常
  • MPI测试程序

    include
  • mysql cmd命令行 创建数据库 表 基础语句

    一 连接MYSQL 格式 mysql h主机地址 u用户名 p用户密码 1 连接到本机上的MYSQL 首先打开DOS窗口 然后进入目录mysql bin 再键入命令mysql u root p 回车后提示你输密码 注意用户名前可以有空格也可
  • A*寻路算法 lua

    function InitMap self AMap for i 1 10 do self AMap i for j 1 10 do local map map x i map y j map g 999 map h 0 map f 0 m
  • 如何运行一个CFDEM tutorial case

    新手入门 万里长征第一步 安装完CFDEM后 我们知道有很多tutorial可以教我们怎么设置合理的参数 很多tutorial case里都有写好的Allrun脚本 最简单的方法就是运行Allrun脚本走一遍流程 准备工作 复制随便一个tu
  • 当里个当,免费的HTML5连载来了《HTML5网页开发实例详解》连载(一)

    读懂 HTML5网页开发实例详解 这本书 你还在用Flash嘛 帮主早不用了 乔布斯生前在公开信 Flash之我见 中预言 像HTML 5这样在移动时代中创立的新标准 将会在移动设备上获得胜利 国际巨头Google 苹果等都支持HTML 5
  • IDEA写爬虫,配jsoup

    环境变量配了 jdk的lib目录下也加了jsoup的jar包 返回IDEA还是没有 点击左上角的File进Project Setting SDKs 选择自己的jdk文件 在右侧点击 把jar包导进来
  • K8S 安装步骤

    K8S 安装步骤 一 为每台机器安装docker 1 安装docker 1 1 卸载旧版本 sudo yum remove docker docker client docker client latest docker common do
  • 【游戏开发】[用代码创建unity5.X的动画状态机]

    不废话 上代码 可能有的人 会质疑 这不是editor的功能吗 是的 但是这个允许在运行时候使用 你们跟一下代码看看继承于哪里就知道了 using UnityEngine using System Collections using Sys
  • JAVA-时间日期格式转换

    第一种方式 获取当前时间然后按照指定格式转换成String类型 DateFormat dateFormat new SimpleDateFormat yyyy MM dd HH mm ss Calendar cal Calendar get
  • 【Shell牛客刷题系列】SHELL31 netstat练习3-输出每个IP的连接数

    该系列是基于牛客Shell题库 针对具体题目进行查漏补缺 学习相应的命令 刷题链接 牛客题霸 Shell篇 该系列文章都放到专栏下 专栏链接为 专栏 Shell 欢迎关注专栏 本文知识预告 本文复习了awk grep sort uniq命令