牛客编程题shell34题(Linux awk,grep命令)
Posted 小哈里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客编程题shell34题(Linux awk,grep命令)相关的知识,希望对你有一定的参考价值。
【牛客编程题】shell34题(Linux awk,grep命令)
SHELL01-22:基本文本处理
SHELL23-28:nginx日志分析
SHELL29-32:netstat练习
做题链接:https://www.nowcoder.com/exam/oj?page=1&tab=SHELL%E7%AF%87&topicId=195
参考资料:https://github.com/jaywcjlove/linux-command
文章目录
- 从awk命令开始
- 对grep命令的补充
- SHELL1 统计文件的行数
- SHELL2 打印文件的最后5行
- SHELL3 输出7的倍数
- SHELL4 输出第5行的内容
- SHELL5 打印空行的行号
- SHELL6 去掉空行
- SHELL7 打印字母数小于8的单词
- SHELL8 统计所有进程占用内存大小的和
- SHELL9 统计每个单词出现的个数
- SHELL10 第二列是否有重复
- SHELL11 转置文件的内容
- SHELL12 打印每一行出现的数字个数
- SHELL13 去掉所有包含this的句子
- SHELL14 求平均值
- SHELL15 去掉不需要的单词
- SHELL16 判断输入的是否为IP地址
- SHELL17 将字段逆序输出文件的每行
- SHELL18 域名进行计数排序处理
- SHELL19 打印等腰三角形
- SHELL20 打印只有一个数字的行
- SHELL21 格式化输出
- SHELL22 处理文本
- SHELL23 nginx日志分析1-IP统计
- SHELL24 nginx日志分析2-统计某个时间段的IP
- SHELL25 nginx日志分析3-统计访问3次以上的IP
- SHELL26 nginx日志分析4-查询某个IP的详细访问情况
- SHELL27 nginx日志分析5-统计爬虫抓取404次数
- SHELL28 nginx日志分析6-统计每分钟的请求数
- SHELL29 netstat练习1-查看各个状态的连接数
- SHELL30 netstat练习2-查看和3306端口建立的连接
- SHELL31 netstat练习3-输出每个IP的连接数
- SHELL32 netstat练习4-输出和3306端口建立连接总的各个状态的数目
- SHELL33 业务分析-提取值
- SHELL34 ps分析-统计VSZ,RSS各自总和
从awk命令开始
awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。
它在命令行中使用,但更多是作为脚本来使用。awk有很多类似于C语言的灵活内建的功能,比如数组、函数等。
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)
-F fs,fs指定输入分隔符,fs可以是字符串或正则表达式,如-F : 。默认的分隔符是连续的空格或制表符。
-v var=value 赋值一个用户定义变量,将外部变量传递给awk
-f scripfile 从脚本文件中读取awk命令
参考资料:https://wangchujiang.com/linux-command/c/awk.html
awk脚本是由模式和操作组成的。
模式可以是以下任意一个:
- /正则表达式/, 关系表达式, 模式匹配表达式(
~
匹配,!~
不匹配), - BEGIN语句块、pattern语句块、END语句块
awk脚本基本结构
awk 'BEGIN print "start" pattern commands END print "end" ' file
第一步:执行BEGIN commands 语句块中的语句;
第二步:从文件或标准输入读取一行,然后执行pattern commands 语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
第三步:当读至输入流末尾时,执行END commands 语句块。
BEGIN和END是可选的,但是如果没有pattern语句块,则默认执行 print ,即打印每一个读取到的行,awk读取的每一行都会执行该语句块。
awk内置变量
NR: 表示记录数,在执行过程中对应于 当前的行号。
NF: 表示字段数,在执行过程中对应于 当前的字段数。
FS:字段分隔符(默认是任何空格)。
使用print $NF可以打印出一行中的最后一个字段,使用$(NF-1)则是打印倒数第二个字段。
打印每一行的第二和第三个字段:awk ' print $2,$3 ' filename
统计文件中的行数:awk 'END print NR ' filename
在读入每一行的时,awk会将NR更新为对应的行号,当到达最后一行NR的值就是最后一行的行号,所以END语句块中的NR就是文件的行数。
将外部变量值传递给awk
借助 -v选项 ,可以将外部值传递给awk
VAR=10000
echo | awk -v VARIABLE=$VAR ' print VARIABLE '
var1="aaa"
var2="bbb"
echo | awk ' print v1,v2 ' v1=$var1 v2=$var2
查找进程pid
netstat -antup | grep 7770 | awk ' print $NF NR' | awk ' print $1'
对grep命令的补充
强大的文本搜索工具
- grep 更适合单纯的查找或匹配文本
- sed 更适合编辑匹配到的文本
- awk 更适合格式化文本,对文本进行较复杂格式处理
grep全面搜索正则表达式并把匹配的行打印出来。用于过滤/搜索的特定字符。
# grep查找
grep "match_pattern" file_1 file_2 file_3 ...
# 查找后,输出除之外的所有行 -v
grep -v "match_pattern" file_name
# 使用正则表达式 -E
# 使用正则表达式 -P 选项:
grep -E "[1-9]+"
grep -P "(\\d3\\-)2\\d4" file_name
# 统计文件或者文本中包含匹配字符串的行数 -c 选项:
grep -c "text" file_name
# 输出包含匹配字符串的行数 -n 选项
grep "text" -n file_name
cat file_name | grep "text" -n
# 在多级目录中对文本进行递归搜索, .表示当前目录。
grep "text" . -r -n
# 忽略匹配样式中的字符大小写:
echo "hello world" | grep -i "HELLO"
SHELL1 统计文件的行数
# 查看文件的'\\n'的数量
wc -l ./nowcoder.txt
# 执行结果
8 ./nowcoder.txt
# 用awk打印第一个数字
wc -l ./nowcoder.txt | awk 'print $1'
SHELL2 打印文件的最后5行
# 查看文件的前5行,可以使用head命令,如
head -5 filename
# 查看文件的后5行,可以使用tail命令,如:
tail -5 filename 或 tail -n 5 filename
# 查看文件中间一段,你可以使用sed命令,如:
sed -n ‘5,20p’ filename
SHELL3 输出7的倍数
#!/bin/bash
for num in 0..500..7; do
echo "$num"
done
SHELL4 输出第5行的内容
# head 命令拿到前五行,再通过通道,通过tail取出来最后一行,即第五行
head -n 5 nowcoder.txt | tail -n 1
# sed 命令中的 p 子命令,打印第五行
sed -n 5p nowcoder.txt
SHELL5 打印空行的行号
# awk是数据解析工具 对文件或管道数据、终端输入数据逐行解析 默认以空格分隔
# awk语法:awk 'pattern命令' 文件名, /pattern/是正则表达式匹配, /^$/表示空字符串
awk '/^$/print NR' nowcoder.txt
SHELL6 去掉空行
# awk 命令,判断当前行的内容然后输出
awk '!/^$/ print $NF' nowcoder.txt
awk 'if($0 != "") print $0' nowcoder.txt
# cat 输出文本内容,然后通过管道符交由 awk 做非空校验然后输出
cat nowcoder.txt | awk NF
# grep 命令 -v 显示不包含匹配文本的所有行
grep -v '^$'
SHELL7 打印字母数小于8的单词
# awk嵌套for
awk -F " " 'for(i=1;i<=NF;i++)if(length($i) < 8)print $i' nowcoder.txt
# 或者循环
for i in $(cat nowcoder.txt); do
if [ $#i -lt 8 ]; then
echo $i
fi
done
SHELL8 统计所有进程占用内存大小的和
# 利用awk的强大功能
awk 'sum+=$6ENDprint sum' nowcoder.txt
SHELL9 统计每个单词出现的个数
# awk天下无敌
awk 'for(i=1;i<=NF;i++) a[$i]+=1ENDfor(x in a) print x,a[x]' nowcoder.txt
SHELL10 第二列是否有重复
# awk
awk 'a[$2]+=1ENDfor(x in a)if(a[x]>1) print a[x],x' nowcoder.txt
SHELL11 转置文件的内容
# awk
awk '
for(i=1;i<=NF;i++)
if(NR==1)
row[i] = $i;
else
row[i] = row[i]" "$i;
END
for(i=1;i<=NF;i++)
print row[i]
' nowcoder.txt
SHELL12 打印每一行出现的数字个数
# awk
awk -F "[1,2,3,4,5]" '
BEGINsum=0
print "line"NR" number:"(NF-1);sum+=(NF-1)
ENDprint "sum is "sum
' nowcoder.txt
SHELL13 去掉所有包含this的句子
# grep 命令 -v 显示不包含匹配文本的所有行
grep -v 'this'
# awk 命令,检查当前 $0 不包含 this 随机输出
awk '$0!~/this/ print $0'
SHELL14 求平均值
awk 'if(NR==1) N=$1 elsesum+=$1 ENDprintf ("%.3f",sum/N) '
SHELL15 去掉不需要的单词
# 使用grep -v去掉
grep -E -v "[bB]"
# awk
awk ' for (i=1; i<=NF; i++) if ($i ~ /.*[bB]+.*/) continue else print $i '
SHELL16 判断输入的是否为IP地址
# 使用 . 作为分隔符
awk -F '.' '
if (NF == 4)
for (i = 1; i < 5; i++)
if ($i > 255 || $i < 0)
print("no")
break
if (i == 5)
print("yes")
else
print("error")
'
SHELL17 将字段逆序输出文件的每行
awk -F ":" 'a[NR]=$NF; for (i=NF-1;i>0;i--) a[NR]=a[NR]":"$i ENDfor(k in a) print a[k]' nowcoder.txt
SHELL18 域名进行计数排序处理
awk -F/ 'print $3'|sort -r|uniq -c|awk 'print $1,$2'
SHELL19 打印等腰三角形
awk 'BEGIN
for(n = 1; n <= 5; n++)
row = "";
for(i = 1;i <= 5 - n; i++)
row = row " "
for(i = 1; i <= n; i++)
row = row "*" " "
print row
'
SHELL20 打印只有一个数字的行
awk -F[1-9] 'if(NF==2)print $0'
SHELL21 格式化输出
awk 'BEGINFS=""for(i=1;i<=NF;i++) if((NF-i)%3==0&&i!=NF) printf $i",";else printf $i;printf "\\n"' nowcoder.txt
SHELL22 处理文本
awk -F ":" '
a[$1] = a[$1] $2 "\\n"
END for (i in a)
printf("[%s]\\n%s",i,a[i])
' nowcoder.txt
SHELL23 nginx日志分析1-IP统计
# 利用 awk 中的 substr 函数
awk '
if(substr($4, 2, 11) == "23/Apr/2020")
res[$1]++;
END
for(k in res)
print res[k] " " k
' | sort -nr -k 1 -t " "
SHELL24 nginx日志分析2-统计某个时间段的IP
# 使用grep
grep "23/Apr/2020" | cut -c '-12' | sort -u | wc -l
# awk
awk '
if ($0 ~ /\\[23\\/Apr\\/2020:2[0-2]/)
a[$1]=1
END
print (length(a))
'
SHELL25 nginx日志分析3-统计访问3次以上的IP
awk '
if ($1 in a)
a[$1]++;
else
a[$1]=1
END
for (j in a)
if (a[j] > 3)
print a[j],j
' nowcoder.txt | sort -r
SHELL26 nginx日志分析4-查询某个IP的详细访问情况
awk '$1=="192.168.1.22"a[$7]++END for(i in a) print a[i],i ' | sort -r
SHELL27 nginx日志分析5-统计爬虫抓取404次数
# grep
grep 'www.baidu.com' nowcoder.txt | grep ' 404 ' | wc -l
# awk
awk '
if ($0 ~ '/www.baidu.com/' && $9 = 404 ) a++
END
print a
' nowcoder.txt
SHELL28 nginx日志分析6-统计每分钟的请求数
awk 'print substr($4,14,5)' | sort | uniq -c | sort -rn -k 1 | awk 'print $1,$2'
SHELL29 netstat练习1-查看各个状态的连接数
awk '/tcp/a[$6]++ENDfor(i in a)print i,a[i]' nowcoder.txt | sort -nrk 2
SHELL30 netstat练习2-查看和3306端口建立的连接
cat nowcoder.txt | grep '3306' | grep 'ESTABLISHED' | awk -F ' ' 'print $5' | awk -F: 'print $1' | sort | uniq -c | sort -nr -k1 | awk 'print $1" "$2'
SHELL31 netstat练习3-输出每个IP的连接数
awk -F "[ :]+" '/tcp/a[$6]++ENDfor(i in a)print i,a[i]' nowcoder.txt | sort -nrk2
SHELL32 netstat练习4-输出和3306端口建立连接总的各个状态的数目
awk '
if ($1 == "tcp" && $5 ~ /3306/)
if ($6 == "ESTABLISHED")
es++
ans++
arr[$5]=0
END
printf("TOTAL_IP %d\\nESTABLISHED %d\\nTOTAL_LINK %d", length(arr), es, ans)
'
SHELL33 业务分析-提取值
awk -F "[:,]" '
if($0~"Server version")
print "serverVersion:" $4;
if($0~"Server number")
print "serverName:" $4;
if($0~"OS Name")
print "osName:" $4;
if($0~"OS Version")
print "osVersion:" $6
'
SHELL34 ps分析-统计VSZ,RSS各自总和
awk '
v += $5
r += $6
END
printf("MEM TOTAL\\nVSZ_SUM:%0.1fM,RSS_SUM:%0.3fM", v/1024, r/1024)
'
以上是关于牛客编程题shell34题(Linux awk,grep命令)的主要内容,如果未能解决你的问题,请参考以下文章