该系列是基于牛客Shell题库,针对具体题目进行查漏补缺,学习相应的命令。
刷题链接:牛客题霸-Shell篇。
该系列文章都放到专栏下,专栏链接为:《专栏:Shell》。欢迎关注专栏~
本文知识预告:
- 本文复习了
awk
命令的相关用法,然后给出了三种题目的解决方案。
SHELL34 ps分析-统计VSZ,RSS各自总和
假设命令运行的结果我们存储在nowcoder.txt里,格式如下:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 37344 4604 ? Ss 2020 2:13 /sbin/init
root 231 0.0 1.5 166576 62740 ? Ss 2020 15:15 /lib/systemd/systemd-journald
root 237 0.0 0.0 0 0 ? S< 2020 2:06 [kworker/0:1H]
root 259 0.0 0.0 45004 3416 ? Ss 2020 0:25 /lib/systemd/systemd-udevd
root 476 0.0 0.0 0 0 ? S< 2020 0:00 [edac-poller]
root 588 0.0 0.0 276244 2072 ? Ssl 2020 9:49 /usr/lib/accountsservice/accounts-daemon
message+ 592 0.0 0.0 42904 3032 ? Ss 2020 0:01 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 636 0.0 0.0 65532 3200 ? Ss 2020 1:51 /usr/sbin/sshd -D
daemon 637 0.0 0.0 26044 2076 ? Ss 2020 0:00 /usr/sbin/atd -f
root 639 0.0 0.0 29476 2696 ? Ss 2020 3:29 /usr/sbin/cron -f
root 643 0.0 0.0 20748 1992 ? Ss 2020 0:26 /lib/systemd/systemd-logind
syslog 645 0.0 0.0 260636 3024 ? Ssl 2020 3:17 /usr/sbin/rsyslogd -n
root 686 0.0 0.0 773124 2836 ? Ssl 2020 26:45 /usr/sbin/nscd
root 690 0.0 0.0 19472 252 ? Ss 2020 14:39 /usr/sbin/irqbalance --pid=/var/run/irqbalance.pid
ntp 692 0.0 0.0 98204 776 ? Ss 2020 25:18 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:114
uuidd 767 0.0 0.0 28624 192 ? Ss 2020 0:00 /usr/sbin/uuidd --socket-activation
root 793 0.0 0.0 128812 3148 ? Ss 2020 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 794 0.0 0.2 133376 9120 ? S 2020 630:57 nginx: worker process
www-data 795 0.0 0.2 133208 8968 ? S 2020 633:02 nginx: worker process
www-data 796 0.0 0.2 133216 9120 ? S 2020 634:24 nginx: worker process
www-data 797 0.0 0.2 133228 9148 ? S 2020 632:56 nginx: worker process
web 955 0.0 0.0 36856 2112 ? Ss 2020 0:00 /lib/systemd/systemd --user
web 956 0.0 0.0 67456 1684 ? S 2020 0:00 (sd-pam)
root 1354 0.0 0.0 8172 440 tty1 Ss+ 2020 0:00 /sbin/agetty --noclear tty1 linux
root 1355 0.0 0.0 7988 344 ttyS0 Ss+ 2020 0:00 /sbin/agetty --keep-baud 115200 38400 9600 ttyS0 vt220
root 2513 0.0 0.0 0 0 ? S 13:07 0:00 [kworker/u4:1]
root 2587 0.0 0.0 0 0 ? S 13:13 0:00 [kworker/u4:2]
root 2642 0.0 0.0 0 0 ? S 13:17 0:00 [kworker/1:0]
root 2679 0.0 0.0 0 0 ? S 13:19 0:00 [kworker/u4:0]
root 2735 0.0 0.1 102256 7252 ? Ss 13:24 0:00 sshd: web [priv]
web 2752 0.0 0.0 102256 3452 ? R 13:24 0:00 sshd: web@pts/0
web 2753 0.5 0.1 14716 4708 pts/0 Ss 13:24 0:00 -bash
web 2767 0.0 0.0 29596 1456 pts/0 R+ 13:24 0:00 ps aux
root 10634 0.0 0.0 0 0 ? S Nov16 0:00 [kworker/0:0]
root 16585 0.0 0.0 0 0 ? S< 2020 0:00 [bioset]
root 19526 0.0 0.0 0 0 ? S Nov16 0:00 [kworker/1:1]
root 28460 0.0 0.0 0 0 ? S Nov15 0:03 [kworker/0:2]
root 30685 0.0 0.0 36644 2760 ? Ss 2020 0:00 /lib/systemd/systemd --user
root 30692 0.0 0.0 67224 1664 ? S 2020 0:00 (sd-pam)
root 32689 0.0 0.0 47740 2100 ? Ss 2020 0:00 /usr/local/ilogtail/ilogtail
root 32691 0.2 0.5 256144 23708 ? Sl 2020 1151:31 /usr/local/ilogtail/ilogtail
现在需要你统计VSZ,RSS各自的总和(以M兆为统计),输出格式如下
MEM TOTAL
VSZ_SUM:3250.8M,RSS_SUM:179.777M
相关命令学习
awk
:文本和数据进行处理的编程语言
awk
命令来自于三位创始人”Alfred Aho,Peter Weinberger, Brian Kernighan “的姓氏缩写,其功能是用于对文本和数据进行处理的编程语言。使用awk
命令可以让用户自定义函数或正则表达式对文本内容进行高效管理,与sed
、grep
并称为Linux系统中的文本三剑客。
语法格式:awk 参数 文件
常用参数:
参数 | 功能 |
---|---|
-F | 指定输入时用到的字段分隔符 |
-v | 自定义变量 |
-f | 从脚本中读取awk 命令 |
-m | 对val 值设置内在限制 |
常用的awk
内置变量:
awk
语法由一系列条件和动作组成,在花括号内可以有多个动作,多个动作之间用分号分隔,在多个条件和动作之间可以有若干空格,也可以没有。
变量名称 | 说明 |
---|---|
FILENAME | 当前输入文档的文件名 |
FNR | 当前输入文档的当前行号,尤其当多个输入文档时有用 |
FS | 设置字段分隔符,默认为空格或制表符 |
NF | 当前记录(行)的字段(列)个数 |
NR | 输入数据流的当前记录数(行号) |
OFS | 输出字段分隔符,默认为空格 |
ORS | 输出记录分隔符,默认为换行符 |
RS | 输入记录分隔符,默认为换行符 |
awk
是一种处理文本文件的编程语言,文件的每行数据都被称为记录,默认以空格或制表符为分隔符,每条记录被分成若干字段(列),awk
每次从文件中读取一条记录。
例子:
- 仅显示指定文件中第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列的内容:
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
文件中的内容由:
分隔开。
- 以冒号为间隔符,显示系统中所有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
- 仅显示指定文件中含有指定关键词
main
的内容:
lucky@DESKTOP-VQ8KID4:~/shell$ awk '/main/{print}' nowcoder.txt
int main()
- 以冒号为间隔符,仅显示指定文件中最后一个字段的内容:
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
- 输出行号,
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
awk
命令的常规用法,好像没啥可说的了🤣不懂的话,评论区Q我吧~
awk '{
V += $5
R += $6
} END {
print "MEM TOTAL"
print "VSZ_SUM:"V/1024"M,RSS_SUM:"R/1024"M"
}'
方法二:echo
+awk
同方法一,只是方法二中使用了数组来保存计数,一样的道理。
echo "MEM TOTAL"
awk '{
if(NR != 1){
arr["VSZ"]+=$5
arr["RSS"]+=$6
}
}END{
print "VSZ_SUM:"arr["VSZ"]/1024"M,RSS_SUM:"arr["RSS"]/1024"M"
}' nowcoder.txt
方法三:纯shell解法
纯shell的解法,思路和前面的方法差不多,注意shell的语法就行了。
vsz=0
for line in $(awk '{print $5}' nowcoder.txt); do
((vsz += $line))
done
vsz_sum=$(echo "scale=1;$vsz/1024" | bc)
rss=0
for line in $(awk '{print $6}' nowcoder.txt); do
((rss += $line))
done
rss_sum=$(echo "scale=3;$rss/1024" | bc)
echo 'MEM TOTAL'
echo "VSZ_SUM:${vsz_sum}M,RSS_SUM:${rss_sum}M"
牛客SHELL刷题系列更完啦,做个总结吧~【以下都是个人见解,勿喷~】
- 列一列最常用的几个命令吧:
awk
、grep
、sed
、sort
、uniq
。这几个命令真的用得很多很多!这其中,绝大部分的题直接用awk
命令就可以解决!!!可见这个命令的重要性了。 - 就知识点而言,一共34道题,其实很多题目考察得命令用法基本是重复的,感觉还需要扩充一些题目,这34道题感觉考察得不全面。
- 还有值得一提得一点是,牛客对于提交代码,判断代码结果正确与否的机制还得改啊!真的有时候很好笑…你说这代码提交上去,也能通过…不过我觉得还挺好玩~🤣🤣🤣
不知道,看到最后一题的人有多少,从博客阅读量来说,真没几个人…中途就准备不写了,最后看着自己做的笔记,想了想,还是继续更新完…给有需要的人提供一点帮助吧~博主也差不多算是初学,写的过程中,难免会有些错误,希望大家看到了提醒我一下,不甚感激。
在最后一题,求个关注!求个点赞!求个收藏!
一起加油呀!