牛客shell编程练习34题带你巩固shell

  • 题目网址:牛客网

文章目录

      • 1、统计文件的行数
      • 2、打印文件的最后5行
      • 3、输出7的倍数
      • 4、输出第5行的内容
      • 5、打印空行的行号
      • 6、去掉空行
      • 7、打印字母数小于8的单词
      • 8、统计所有进程占用内存大小的和
      • 9、统计每个单词出现的个数
      • 10、第二列是否有重复
      • 11、转置文件的内容
      • 12、打印每一行出现的数字个数
      • 13、去掉所有包含this的句子
      • 14、求平均值
      • 15、去掉不需要的单词
      • 16、判断输入的是否为IP地址
      • 17、将字段逆序输出文件的每行
      • 18、域名进行计数排序处理
      • 19、打印等腰三角形
      • 20、打印只有一个数字的行
      • 21、格式化输出
      • 22、处理文本
      • 23、nginx日志分析1-IP统计
      • 24、nginx日志分析2-统计某个时间段的IP
      • 25、nginx日志分析3-统计访问3次以上的IP
      • 26、nginx日志分析4-查询某个IP的详细访问情况
      • 27、nginx日志分析5-统计爬虫抓取404的次数
      • 28、nginx日志分析6-统计每分钟的请求数
      • 29、netstat练习1-查看各个状态的连接数
      • 30、netstat练习2-查看和3306端口建立的连接
      • 31、netstat练习3-输出每个IP的连接数
      • 32、netstat练习4-输出和3306端口建立连接总的各个状态的数目
      • 33、业务分析-提取值
      • 34、ps分析-统计VSZ,RSS各自总和

1、统计文件的行数

cat nowcoder.txt | wc -l     # wc -l统计行数专用 
grep -c  '' nowcoder.txt     # grep 过滤 -c计数(count) ''无条件 ; 对所有行计数 
sed -n '$=' nowcoder.txt     # sed -n不打印模式空间; 
awk 'END{print NR}' nowcoder.txt # NR行数; 必须加END,因为shell是一行一行读取,否则会输出n行NR值; END表示只执行一次print NR 

2、打印文件的最后5行

tail -n 5 nowcoder.txt
tail -5 nowcoder.txt

3、输出7的倍数

  • 写一个 bash脚本以输出数字 0 到 500 中 7 的倍数(0 7 14 21…)的命令
seq 0 7 500
seq 0 500 | awk '$0%7==0{print $0}'

#!/bin/bash
for ((i=0;i<=500;i++));do 
    if [ $(($i%7)) -eq 0 ];then
        echo $i
    fi
done

[hadoop1@hadoop1 test]$ bash ./a.sh

4、输出第5行的内容

[hadoop1@hadoop1 test]$ sed -n '5p' nowcoder.txt
[hadoop1@hadoop1 test]$ awk 'NR==5' nowcoder.txt

5、打印空行的行号

[hadoop1@hadoop1 test]$ grep -n '^$' nowcoder.txt # 会显示 (行号:) 不通过  (-n改为-c即为空行计数)
[hadoop1@hadoop1 test]$ grep -n '^$' nowcoder.txt | awk -F: '{print $1}' # 上述结果按照冒号分割取第一列就可以只取行号了
[hadoop1@hadoop1 test]$ sed -n '/^$/=' nowcoder.txt # -n不打印模式空间; =打印行号(p打印行内容); /^$/空行
[hadoop1@hadoop1 test]$ awk '/^$/{print NR}' nowcoder.txt

6、去掉空行

[hadoop1@hadoop1 test]$ sed -n '/^$/!p' nowcoder.txt  # sed !p不打印符合条件的
[hadoop1@hadoop1 test]$ grep -v '^$' nowcoder.txt # # -v 取反
[hadoop1@hadoop1 test]$ awk NF nowcoder.txt # NF判断该行是否有内容;若有,返回值1;没有返回值0;这里NF直接输出不为空行的内容

7、打印字母数小于8的单词

# 由于awk是按行读取数据的,因此NF(列数)每行可能都不同; 
[hadoop1@hadoop1 test]$ awk '{for(i=1;i<=NF;i++)if(length($i)<8)print $i}' nowcoder.txt

8、统计所有进程占用内存大小的和

# $6第六列表示内存占用大小 ; sum内存和变量,默认初始为0 
[hadoop1@hadoop1 test]$ awk '{sum+=$6}END{print sum}' nowcoder.txt 

9、统计每个单词出现的个数

# 按行读取.第一个{}意思是对每列遍历读取,数组计数; 第2个{}遍历数组,输出i(下标),array[i](次数) 
[hadoop1@hadoop1 test]$ awk '{for(i=1;i<=NF;i++)array[$i]++}END{for(i in array)print i,array[i]}' nowcoder.txt

10、第二列是否有重复

[hadoop1@hadoop1 test]$ awk '{array[$2]++}END{for(i in array)if(array[i]>=2)print i}' nowcoder.txt 
# 下面为计算过程 
	# 对第2列数组分组计数
[hadoop1@hadoop1 test]$ awk '{array[$2]++}END{for(i in array)print i,array[i]}' nowcoder.txt
java 2
go 3
c 1
shell 1
php 1
c++ 1
python 1
	# 分组计数后,筛选出次数大于1的字符
[hadoop1@hadoop1 test]$ awk '{array[$2]++}END{for(i in array)if(array[i]>=2)print array[i],i}' nowcoder.txt
2 java
3 go

11、转置文件的内容

[hadoop1@hadoop1 test]$ awk  '{a=(a""$1" ");b=(b""$2" ")}END{print a"\n"b}' s.txt

#!/bin/bash
a=$( cat s.txt | awk '{print $1}' )
b=$( cat s.txt | awk '{print $2}' )
echo $a
echo $b
[hadoop1@hadoop1 test]$ ./s.sh

# 变回去 
[hadoop1@hadoop1 test]$ awk  '{a=(a""$1" ");b=(b""$2" ")}END{print a"\n"b}' s.txt |awk  '{a=(a""$1" ");b=(b""$2" ");c=(c""$3" ");d=(d""$4" ")}END{print a"\n"b"\n"c"\n"d}'
job salary 
c++ 13 
java 14 
php 12 

12、打印每一行出现的数字个数

# 将数字作为分隔符 则产生NF个字段, NF-1即为数字个数
[hadoop1@hadoop1 test]$ awk -F"[1-5]" '{print "line"NR " " "number:"NF-1;sum+=(NF-1)}END{print "sum is "sum"}' nowcoder.txt

# 脚本写法
#!/bin/awk -f
BEGIN{
    sum=0
} # sum=0可写可不写 默认为0
{
    print "line"NR " " "number:"NF-1
    sum+=(NF-1)
}
END{
    print "sum is "sum
}

[hadoop1@hadoop1 test]$ awk -F"[1-5]" -f  nowcoder.awk nowcoder.txt

13、去掉所有包含this的句子

# grep 筛选 -v取反
[hadoop1@hadoop1 test]$ grep -v 'this' nowcoder.txt  
# sed !p不打印符合条件的行 -n不打印模式空间(全部的原数据) 
[hadoop1@hadoop1 test]$ sed -n '/this/!p' nowcoder.txt
# awk $0整行内容 !~ 不包含 
[hadoop1@hadoop1 test]$ awk '$0!~/this/{print $0}' nowcoder.txt

14、求平均值

  • 第1行为输入的数组长度N,第2~N行为数组的元素
# 对第二行之后的进行求和计算, NR行数, NR-1数字的个数, printf 输出格式化
[hadoop1@hadoop1 test]$ awk 'NR>=2{sum+=$1}END{printf "%.3f\n",sum/(NR-1)}' nowcoder.txt
# 读取第一行数组长度N, 在对第二行及之后的数字求和  
[hadoop1@hadoop1 test]$ awk 'NR==1{N=$1}NR>=2{sum+=$1}END{printf "%.3f\n",sum/N}' nowcoder.txt

15、去掉不需要的单词

  • 去掉输入中的含有B和b的单词。输入格式:一行一个单词;输出格式 :将所有单词放入一行中
# grep sed 输出格式都是按行分割的
[hadoop1@hadoop1 test]$ grep -v '[Bb]' s.txt
nowcoder
test
[hadoop1@hadoop1 test]$ sed -n '/[Bb]/!p' s.txt
nowcoder
test
# awk 可以通过字符串连接{a=a""$0" "}以空格分割将其展示在一行中 
[hadoop1@hadoop1 test]$ awk '$0!~/[Bb]/{a=a""$0" "}END{print a}' s.txt
nowcoder test 

16、判断输入的是否为IP地址

  • 写一个脚本统计文件nowcoder.txt中的每一行是否是正确的IP地址。
    如果是正确的IP地址输出:yes;如果是错误的IP地址,四段号码的话输出:no,否则的话输出:error
  • 思路: 以“.”分割ip;ip地址四个段范围都是在0—255间的;若没有四段号码,则为error;若有四段号码但四个值不在[0,255]之间,则为no;否则为yes。
#!/bin/awk -f
{
if(NF!=4)
    print "error"
elif (($1>=0&&$1<=255) && ($2>=0&&$2<=255) && ($3>=0&&$3<=255) && ($4>=0&&$4<=255))
    print "yes"
else
    print "no"
}

[hadoop1@hadoop1 test]$ awk -F"." -f  a.awk nowcoder.txt

17、将字段逆序输出文件的每行

  • 将字段逆序输出文件nowcoder.txt的每一行,其中每一字段都是用英文冒号: 相分隔。
#!/bin/awk -f
{
for(i=NF;i>=1;i--){
	if (i==1){
		print $1
		break;
	}
	printf($i":")
	}
}

18、域名进行计数排序处理

  • 假设我们有一些域名,存储在nowcoder.txt里,现在需要你写一个脚本,将域名取出并根据域名进行计数排序处理。网址:http://www.nowcoder.com/index.html;域名:www.nowcoder.com
[hadoop1@hadoop1 test]$ awk -F"/" '{array[$3]++}END{for (i in array) print array[i],i}' s.txt | sort -rnk1

19、打印等腰三角形

[hadoop1@hadoop1 test]$ awk '{
 for(i=5;i>0;i--){
  str="";
  for(j=i-1;j>0;j--) str=str OFS;
  for(j=0;j<6-i;j++) str=str "*" OFS;
  print str;
 }
}'

20、打印只有一个数字的行

# 如果只有1个数字,那么根据数字分割字符会出现0列或2列
[hadoop1@hadoop1 test]$ awk -F "[0-9]" '(NF==2||NF==0){print $0}'  nowcoder.txt

21、格式化输出

# xargs -nl
[hadoop1@hadoop1 test]$ cat s.txt | xargs -n1  printf "%'d\n"

22、处理文本

[hadoop1@hadoop1 test]$ awk -F ":" '{
    res[$1] = (res[$1] == "" ? $2 : (res[$1] "\n" $2))
}END{
    for(k in res){
        print "["k"]"
        print res[k]
    }
}' nowcoder.txt

23、nginx日志分析1-IP统计

  • 现在需要你统计出2020年4月23号的访问ip次数,并且按照次数降序排序。
  • 日志样式:192.168.1.20 - - [21/Apr/2020:14:27:49 +0800] “GET /1/index.php HTTP/1.1” 404 490 “-” “Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0”
  • 输出格式: 5 192.168.1.22 (次数 ip)
[hadoop1@hadoop1 test]$ awk  '/(23\/Apr\/2020)/{array[$1]++}END{for(i in array) print(array[i],i)}' nowcoder.txt | sort -rnk1
# sort -r逆序 -n数值型排序 -k1 指定排序字段

24、nginx日志分析2-统计某个时间段的IP

  • 现在你需要统计2020年04月23日20-23点的去重IP访问量
  • 思路:范围筛选时间,利用数组对ip分组计数达到去重效果,最后输出数组长度
  • 小问题:20—23点包含23点整吗? 不包含的话正则就可以到22ok了 否则还还要匹配23:00:00
[hadoop1@hadoop1 test]$ awk '/(23\/Apr\/2020:20)/,/(23\/Apr\/2020:22)/{array[$1]++}END{print(length(array))}' nowcoder.txt
# 参考评论区的 : 找到符合条件的ip,排序sort 去重uniq 计数wc -l ; uniq相同ip必须要挨着才去重 
[hadoop1@hadoop1 test]$ awk  -r '/(23\/Apr\/2020:20)/,/(23\/Apr\/2020:22)/{print($1)}' nowcoder.txt | sort |uniq | wc -l

25、nginx日志分析3-统计访问3次以上的IP

  • 思路:数组分组计数,循坏判断访问次数是否大于3
[hadoop1@hadoop1 test]$ awk '{array[$1]++}END{for(i in array)if(array[i]>3)print(array[i],i)}' nowcoder.txt | sort -rnk1

26、nginx日志分析4-查询某个IP的详细访问情况

  • 需要你查询192.168.1.22的详细访问情况,按访问频率降序排序
  • 输出格式:4 /1/index.php (次数 网址)
[hadoop1@hadoop1 test]$ awk '/192.168.1.22/{array[$7]++}END{for(i in array)print(array[i],i)}' nowcoder.txt|sort -rnk1

27、nginx日志分析5-统计爬虫抓取404的次数

  • 需要你统计百度爬虫抓取404的次数
  • 思路:两个条件 :百度和404
[hadoop1@hadoop1 test]$ awk '/http:\/\/www.baidu.com/&&$9==404' nowcoder.txt | wc -l
# 其它方法 sed 和 grep 多条件查询  awk方法更准确 因为可能其它列会出现404 影响结果
[hadoop1@hadoop1 test]$ grep -E 'http:\/\/www.baidu.com' nowcoder.txt | grep '404' | wc -l
[hadoop1@hadoop1 test]$ sed -n '/http:\/\/www.baidu.com/{/404/p}' nowcoder.txt | wc -l
[hadoop1@hadoop1 test]$ grep -E 'http:\/\/www.baidu.com' nowcoder.txt | grep -c '404' 

28、nginx日志分析6-统计每分钟的请求数

  • 现在需要你统计每分钟的请求数,并且按照请求数降序排序
# 利用sed s///g和()分组取出时分; 利用awk数组对时间分组计数 
[hadoop1@hadoop1 test]$ sed -r 's/^.*[0-9]{4}:([0-9]{2}:[0-9]{2}):[0-9]{2}.*$/\1/g' nowcoder.txt | awk '{array[$1]++}END{for(i in array)print(array[i],i)}' | sort -rnk1
# 利用awk对原数据按照:分割 将第2(时)和3(分)列按照:连接; 数组分组计数
[hadoop1@hadoop1 test]$ awk -F":" 'a=$2":"$3{array[a]++}END{for(i in array)print(array[i],i)}' nowcoder.txt | sort -rnk1

29、netstat练习1-查看各个状态的连接数

  • 需要你查看系统tcp连接中各个状态的连接数,并且按照连接数降序输出
awk '$1=="tcp"{array[$6]++}END{for(i in array)print(i,array[i])}' nowcoder.txt | sort -rnk2

30、netstat练习2-查看和3306端口建立的连接

  • 需要你查看和本机3306端口建立连接并且状态是established的所有IP,按照连接数降序排序
# grep筛选出3306和established的行 awk取第五列ip:端口; awk按:分割,对第一列进行数组计数
[hadoop1@hadoop1 test]$ cat nowcoder.txt |grep '3306.*ESTABLISHED'| awk '{print $5}'| awk -F":" '{array[$1]++}END{for(i in array)print(array[i],i)}'|sort -rnk1

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

awk '$1=="tcp"{print $5}' nowcoder.txt|awk -F: '{array[$1]++}END{for(i in array)print(i,array[i])}' | sort -rnk2

32、netstat练习4-输出和3306端口建立连接总的各个状态的数目

  • 输入格式:tcp 0 0 172.16.56.200:41856 172.16.34.144:3306 ESTABLISHED
  • 输出格式:TOTAL_IP 3 \n ESTABLISHED 20 \n TOTAL_LINK 20
  • 思路:输出的是ip数,state总数及各个state数 只需第五列和第六列即可,同时将这两列按:分割输出;按:分割数据产生3列(ip 端口 state),分别对ip和state数组分组计数;最后简单计算循环输出即可
awk '$5~/3306/{print $5":"$6}' nowcoder.txt|awk -F"[:]+" 
'
{ip[$1]++;state[$3]++}

END{
{print("TOTAL_IP",length(ip))}
 
for (i in state)
    print(i,state[i]) 

for (i in ip)
    sum+=ip[i]
print("TOTAL_LINK",sum)
   }
'

33、业务分析-提取值

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
    }
}'

34、ps分析-统计VSZ,RSS各自总和

[hadoop1@hadoop1 test]$ awk 
'NR>1
{vsz_sum+=$5;rss_sum+=$6}
END{
print("MEM TOTAL" "\n" "VSZ_SUM:" vsz_sum/1024"M" ",RSS_SUM:" rss_sum/1024"M")
}
' nowcoder.txt

你可能感兴趣的:(大数据类,bash,开发语言,linux,c语言)