当前位置:   article > 正文

[轻松学会shell编程]-3、grep、正则表达式、awk的详细用法、分析系统自带的两个文件(functions和network)_cat /etc/init.d/openssh grep -v 'a#'i grep -v a$

cat /etc/init.d/openssh grep -v 'a#'i grep -v a$

目录

1、通配符

2、正则表达式

2.1、grep使用正则的语法

2.1.1、-i、-o、-n

2.1.2、 -A、-B、-C

2.1.3、-v(按行取反)和中括号中尖括号(对单个字符取反,更加细节一点)

2.1.4、-r

2.2、单词以什么开头以什么结尾

2.2.1、\s表示一个空白(空格或者tab)

2.3、正则表达式由下列元素构成

2.3.1、显示有效行

2.4、通用修饰符

2.4.1、转义字符

2.5、正则表达式分组

2.6、正则练习

2.6.1、写一个邮箱的正则

2.7、关于时间的正则表达

 3、awk

3.1、分隔符

3.1.1、OFS输出分隔符

3.1.2、FS输入分隔符

3.2、awk命令的基本语法

3.2.1、只有模式没有动作结果的awk命令和grep的作用一样

3.2.2、$NF和$NR

3.2.3、awk命令的操作符( 模糊匹配和精准匹配)

3.2.4、awk基本命令示例

3.3、awk命令的内部变量

3.3.1、内部变量的使用实例

3.4、linux可以生成csv文件,然后传入windows里边,用excel答案开

3.5、小练习(含有watch和split的使用方法)

3.6、-F使用小技巧

4、awk命令引用shell变量问题

4.1、-v,引入shell变量

4.2、使用双引号,但是$符号需要转义

5、awk内置函数

5.1、length

5.2、toupper和tolower

5.3、split

5.4、substr

6、流控(if和for)

6.1、if

6.1.1、单分支和双分支

6.1.2、多分支

6.1.3、总结

6.2、for

6.2.1、自增(awk的行求和)

7、awk数组

7.1、一列中有重复的值,但是对应的另一列的内容一直不一样,想要实现累加功能。

7.2、awk数组小练习

7.2.1、输出文本的第一行和最后一行

7.2.2、已知一台服务器netstat -an 输出格式如下

7.2.3、计算nginx日志 

8、分析操作系统自带的脚本(/etc/init.d/functions和/etc/init.d/network)

8.1、functions

8.2、bash自带的处理字符串


1、通配符

  1. ################# 只需要筛选出满足[]中至少一个元素的行出来就行了
  2. [root@fttswlp grep]# cat passwd |tail|egrep "[azxhoui\-]"
  3. wujin_son:x:7793:7793::/home/wujin_son:/bin/bash
  4. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  5. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  6. cali:x:7796:7796::/home/cali:/bin/bash
  7. dengjz:x:7797:7790::/home/dengjz:/bin/bash
  8. xiaohui:x:7798:7797::/home/xiaohui:/bin/bash
  9. tcpdump:x:72:72::/:/sbin/nologin
  10. test:x:7799:7799::/home/test:/bin/bash
  11. mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
  12. xiaohui\hhh:x:7798:7797::/home/xiaohui:/bin/bash
  13. ######## {} 是扩展正则,所以需要使用"egrep"或者"grep -E"
  14. [root@fttswlp grep]# cat passwd |tail|egrep "[azxhoui\-]{6}"
  15. xiaohui:x:7798:7797::/home/xiaohui:/bin/bash
  16. xiaohui\hhh:x:7798:7797::/home/xiaohui:/bin/bash

2、正则表达式

基本正则:^ $ . *

扩展正则:| + ? {} 

2.1、grep使用正则的语法

用途:使用正则表达式搜索文本,并把匹配的行打印出来

格式:grep [选项] ...  模式  目标

  • -v,反转查找,输出和模式不相符的行
  • -An,同时显示符合条件行的后面的n行
  • -Bn,同时显示符合条件行的前面的n行
  • -Cn,同时显示符合条件行的前后的n行
  • -E,支持扩展正则表达式
  • -o,仅显示匹配模式的字符串
  • -f,根据文件内容进行匹配
  •  -i,不区分大小写
  • -n,显示行号
  • -c,计算找到的符合行的次数
  • -r,递归查找,查找出文件夹里的所有的文件和文件夹里文本文件都查找一遍
  1. #试验文件
  2. [root@fttswlp grep]# cat test
  3. wujin_son:x:7793:7793::/home/wujin_son:/bin/bash
  4. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  5. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  6. cali:x:7796:7796::/home/cali:/bin/bash
  7. CALI:x:7796:7796::/home/cali:/bin/bash
  8. dengjz:x:7797:7790::/home/dengjz:/bin/bash

2.1.1、-i、-o、-n

  1. [root@fttswlp grep]# grep -i cali test
  2. cali:x:7796:7796::/home/cali:/bin/bash
  3. CALI:x:7796:7796::/home/cali:/bin/bash
  4. [root@fttswlp grep]# grep -i -o cali test
  5. cali
  6. cali
  7. CALI
  8. cali
  9. [root@fttswlp grep]# grep -i -o -n cali test
  10. 4:cali
  11. 4:cali
  12. 5:CALI
  13. 5:cali

2.1.2、 -A、-B、-C

  1. [root@fttswlp grep]# grep -A 1 wangchen_son test
  2. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  3. cali:x:7796:7796::/home/cali:/bin/bash
  4. [root@fttswlp grep]# grep -B 1 wangchen_son test
  5. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  6. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  7. [root@fttswlp grep]# grep -C 1 wangchen_son test
  8. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  9. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  10. cali:x:7796:7796::/home/cali:/bin/bash

2.1.3、-v(按行取反)和中括号中尖括号(对单个字符取反,更加细节一点)

  1. [root@fttswlp grep]# grep -v wangchen_son test
  2. wujin_son:x:7793:7793::/home/wujin_son:/bin/bash
  3. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  4. cali:x:7796:7796::/home/cali:/bin/bash
  5. CALI:x:7796:7796::/home/cali:/bin/bash
  6. dengjz:x:7797:7790::/home/dengjz:/bin/bash
  7. ##########
  8. [root@fttswlp grep]# cat test |egrep -v "[0-Z]"
  9. [root@fttswlp grep]# cat test |egrep "[^0-Z]"
  10. wujin_son:x:7793:7793::/home/wujin_son:/bin/bash
  11. songqingshu_son:x:7794:7794::/home/songqingshu_son:/bin/bash
  12. wangchen_son:x:7795:7795::/home/wangchen_son:/bin/bash
  13. cali:x:7796:7796::/home/cali:/bin/bash
  14. CALI:x:7796:7796::/home/cali:/bin/bash
  15. dengjz:x:7797:7790::/home/dengjz:/bin/bash

2.1.4、-r

  1. [root@fttswlp grep]# grep -r "dengjz" .
  2. ./passwd:dengjz:x:7797:7790::/home/dengjz:/bin/bash
  3. ./test:dengjz:x:7797:7790::/home/dengjz:/bin/bash

2.2、单词以什么开头以什么结尾

  1. [root@fttswlp grep]# cat name.txt
  2. liuyifei yifeiliu feiliuyi
  3. [root@fttswlp grep]# cat name.txt |grep "\bliu"
  4. liuyifei yifeiliu feiliuyi
  5. [root@fttswlp grep]# cat name.txt |grep "liu\b"
  6. liuyifei yifeiliu feiliuyi
  7. [root@fttswlp grep]# cat name.txt |grep "\bliuyifei\b"
  8. liuyifei yifeiliu feiliuyi

2.2.1、\s表示一个空白(空格或者tab)

  1. [root@fttswlp grep]# cat name.txt
  2. liuyifei yifeiliu feiliuyi
  3. zhou jielun lin junjie
  4. [root@fttswlp grep]# cat name.txt |egrep "zhou\sjielun"
  5. zhou jielun lin junjie
  6. [root@fttswlp grep]# cat name.txt |egrep "lin\sjunjie"
  7. ### 表示两个以上的空白
  8. [root@fttswlp grep]# cat name.txt |egrep "lin\s{2,}junjie"
  9. zhou jielun lin junjie
  10. [root@fttswlp grep]# cat name.txt |egrep "lin\s+junjie"
  11. zhou jielun lin junjie

2.3、正则表达式由下列元素构成

2.3.1、显示有效行

  1. [root@fttswlp grep]# cat /etc/ssh/sshd_config |egrep -v "^#|^$"
  2. HostKey /etc/ssh/ssh_host_rsa_key
  3. HostKey /etc/ssh/ssh_host_ecdsa_key
  4. HostKey /etc/ssh/ssh_host_ed25519_key
  5. SyslogFacility AUTHPRIV
  6. AuthorizedKeysFile .ssh/authorized_keys
  7. PasswordAuthentication yes
  8. ChallengeResponseAuthentication no
  9. GSSAPIAuthentication yes
  10. GSSAPICleanupCredentials no
  11. UsePAM yes
  12. X11Forwarding yes
  13. AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
  14. AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
  15. AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
  16. AcceptEnv XMODIFIERS
  17. Subsystem sftp /usr/libexec/openssh/sftp-server

2.4、通用修饰符

  • "?":表示前边的字符出现0个或者1个(扩展)
  • "*":表示前边的字符出现0个或者多个
  • "+":表示前边的字符出现1个以上(扩展)
  • {n}:表示前边的字符出现n个
  • {n, m}:表示前边的字符出现n个到m个
  • .*:表示任意字符

 

 

 

2.4.1、转义字符

若是想要把元字符变成普通的没有特殊含义的字符,那么就是要加上"\",若是没有用的话,那么就用"\\"

2.5、正则表达式分组

 f(oo)*:表示(oo)出现n次         (oo|ee){2}:表示oo或者ee出现两次

2.6、正则练习

  1. # 2
  2. [root@fttswlp grep]# egrep "ftp|mail" passwd
  3. mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
  4. ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
  5. # 3
  6. [root@fttswlp grep]# egrep "^[^rfm]" passwd
  7. [root@fttswlp grep]# egrep -v "^[rfm]" passwd
  8. # 4
  9. [root@fttswlp grep]# grep "bash$" passwd
  10. # 5
  11. [root@fttswlp grep]# egrep -v "^#|^$" /etc/login.defs
  12. # 6(若是找不出来的话,可以换个文件或者这个查找的字母个数变小点)
  13. [root@fttswlp grep]# egrep "\b[a-Z]{16}\b" /var/log/messages
  14. # 7
  15. [root@fttswlp grep]# egrep ".*liu.*bash$" passwd
  16. # 9
  17. [root@fttswlp grep]# egrep "\b[0-9]{2}\b" /etc/ssh/ssh_config
  18. # 10(因为这是按行输出)
  19. [root@fttswlp grep]# egrep "[^0-Z]" /etc/ssh/ssh_config
  20. # 11
  21. [root@fttswlp rough_book]# egrep -v "[0-9]" /etc/ssh/ssh_config
  1. # 14
  2. [root@fttswlp grep]# egrep "[a-Z]+://([0-Z]+\.){2}[0-Z]+(\.[0-Z]+)?" web.txt

  1. # 16 C类IP地址的正则表达式
  2. [root@fttswlp ~]# netstat -anplut|egrep "(19[2-9]|2[01][0-9]|22[0-3])(\.([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}"
  3. tcp 0 44 192.168.29.128:22 192.168.29.1:52496 ESTABLISHED 1675/sshd: root@pts
  4. # 自己可以尝试一下写出A、B类的正则表达式

2.6.1、写一个邮箱的正则

2.7、关于时间的正则表达

下面的文件只是从历史的数据文件中分析的,不是实时的文件

练习1:

  1. [root@fttswlp time]# cat access.log |egrep "18/Dec/2021:16:5[4-8]:[0-5][0-9]"|awk '{sum+=$10}END{print sum}'
  2. 482338
  3. # awk在处理数据,是按行处理的,每次都把数据给sum(这个sum只是一个变量名)。最后用"END"打印最后的值
  4. # 这样可以看的更加的清楚,只是加了一些标识,让我们更加了解这个过程
  5. [root@fttswlp time]# cat access.log |egrep "18/Dec/2021:16:5[4-8]:[0-5][0-9]"|awk 'BEGIN{print "start"}{print "行号"NR;sum+=$10;print sum}END{print sum}'

练习2:

 

  1. [root@fttswlp time]# cat scan_day.sh
  2. #!/bin/bash
  3. >min2.txt
  4. for i in {00..24}
  5. do
  6. for j in {00..59}
  7. do
  8. if cat access.log |egrep "18/Dec/2021:$i:$j:[0-5][0-9]" >>/dev/null
  9. then
  10. echo "$i:$j">>min2.txt
  11. cat access.log |egrep "18/Dec/2021:$i:$j:[0-5][0-9]"|awk '{a+=$10}END{print a}' >>min2.txt
  12. fi
  13. done
  14. done

 2.算出2022年7月份里的每一个分钟的流量,具体日志文件格式如下: 
2022-7-1 00:01:01 78
2022-7-1 00:01:04 89
2022-7-1 00:03:01 178
2022-7-1 00:03:05 890
2022-7-2 00:03:01 178
2022-7-3 00:03:05 890
....
2022-7-30 00:03:01 178
2022-7-31 00:07:05 8900

可自行编辑数据

  1. [root@fttswlp 9_74]# awk '{time[$1,substr($1,5,1)substr($2,1,5)]+=$3}END{for (i in time)print i,time[i]}' test.txt |sort -n -k 3 -t -
  2. 2022-7-1-00:01 167
  3. 2022-7-1-00:03 1068
  4. 2022-7-2-00:03 178
  5. 2022-7-3-00:03 890
  6. 2022-7-5-10:03 890
  7. 2022-7-5-12:03 890
  8. 2022-7-5-19:03 5213
  9. 2022-7-6-20:03 800
  10. 2022-7-10-12:08 900
  11. 2022-7-11-16:33 5130
  12. 2022-7-30-00:03 178
  13. 2022-7-31-00:07 8900

 3、awk

文本三剑客之一:awk 

awk的引入:

  1. [root@fttswlp awk]# cat tongji.txt |awk '{pro[$1] += $3}END{ for (i in pro) print i, pro[i] }'
  2. 河南 3
  3. 江西 9
  4. 山东 12
  5. # "cat tongji.txt |awk '{pro[$1] += $3}"这段命令会成成pro,pro={'山东':12,"河南":3,"江西":9}。然后后边又使用了for循环

 上面这个结果是利用了数组的性质

用for循环执行数组的输出 

 

3.1、分隔符

3.1.1、OFS输出分隔符

  1. [root@fttswlp time]# awk -F : 'OFS="#"{print$1,$3}' /etc/passwd
  2. dengjz#7797
  3. xiaohui#7798
  4. tcpdump#72
  5. test#7799
  6. mysql#27

3.1.2、FS输入分隔符

  1. [root@fttswlp time]# awk 'BEGIN{FS=":"}OFS="#"{print$1,$3}' /etc/passwd
  2. 这个命令和上边的效果是一样的

3.2、awk命令的基本语法

 

3.2.1、只有模式没有动作结果的awk命令和grep的作用一样

  1. [root@fttswlp ~]# cat /etc/passwd | awk '/feng/'
  2. califeng:x:1008:1008::/home/califeng:/bin/bash

我们都知道awk的命令中要使用单引号,那么可不可以使用双引号呢?答案是可以的,但是要加入一些东西。

  1. [root@fttswlp ~]# w|awk '{print $2}'
  2. up
  3. TTY
  4. pts/0
  5. [root@fttswlp ~]# w|awk "{print \$2}"
  6. up
  7. TTY
  8. pts/0
  1. # 匹配第一个字段中以h开头的行
  2. [root@fttswlp ~]# awk -F : '/^h/{print $1,$7}' /etc/passwd
  3. halt /sbin/halt

3.2.2、$NF和$NR

$NF取最后一个;$NR取最开始的一个

  1. [root@fttswlp ~]# awk -F [/:] '{print $1,$7,$NF,$(NF-1)}' /etc/passwd | head -5
  2. root root bash bin
  3. bin bin nologin sbin
  4. daemon sbin nologin sbin
  5. adm var nologin sbin
  6. lp var nologin sbin

3.2.3、awk命令的操作符( 模糊匹配和精准匹配)

模糊匹配(~):匹配的行要是包含关系

  1. # 第一段要以数字结尾
  2. [root@fttswlp ~]# awk -F : '$1 ~ /[0-9]$/{print $1,$7}' /etc/passwd
  3. cali123 /bin/bash
  4. fan1 /bin/bash
  5. fan2 /bin/bash
  6. # 第一段要以数字结尾且第三个字段要大于1005
  7. [root@fttswlp ~]# awk -F : '$1 ~ /[0-9]$/ && $3>1005{print $1,$7,$3}' /etc/passwd
  8. cali123 /bin/bash 1009
  9. fan1 /bin/bash 7800
  10. fan2 /bin/bash 7801
  11. # 第三段要是3位数的
  12. [root@fttswlp ~]# awk -F : '$3 ~ /\<[0-9]{3}\>/ {print $1,$3}' /etc/passwd
  13. systemd-network 192
  14. polkitd 999
  15. chrony 998
  16. nginx 997

精准匹配(==):匹配的行要一摸一样

  1. [root@fttswlp ~]# awk -F : '$1 == "fan1" && $3>1005{print $1,$7,$3}' /etc/passwd
  2. fan1 /bin/bash 7800

3.2.4、awk基本命令示例

  1. # 找出100以内,以1开头的或者能够被5整除的数
  2. [root@fttswlp ~]# seq 100 |awk '$1 % 5 == 0 || $1 ~ /^1/{print $1}'

  1. [root@fttswlp ~]# cat /etc/passwd|awk -F : 'BEGIN{i=1}$1 ~ /user/ || $3>1000{i++;print $1,$3}END{print "出现的次数为" i}'
  2. # 显示/etc/passwd文件中第一段有user或者第三段的数值大于1000的行,并统计这些行出现了多少次

3.3、awk命令的内部变量

3.3.1、内部变量的使用实例

  1. [root@fttswlp ~]# awk 'NR ~ /^[0-9]$/ {print NR,$o}' /etc/passwd
  2. 1 root:x:0:0:root:/root:/bin/bash
  3. 2 bin:x:1:1:bin:/bin:/sbin/nologin
  4. 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
  5. 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
  6. 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  7. 6 sync:x:5:0:sync:/sbin:/bin/sync
  8. 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
  9. 8 halt:x:7:0:halt:/sbin:/sbin/halt
  10. 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

3.4、linux可以生成csv文件,然后传入windows里边,用excel答案开

  1. [root@fttswlp rough_book]# awk -F : 'OFS="," {print $1,$3,$4}' /etc/passwd >name.csv
  2. [root@fttswlp rough_book]# cat name.csv |head -5
  3. root,0,0
  4. bin,1,1
  5. daemon,2,2
  6. adm,3,4
  7. lp,4,7
  8. ###### 然后可以把这个文件传到Windows里边,然后再用excel打开。会自动按照","去进行分列

3.5、小练习(含有watch和split的使用方法)

提示1:例题7中使用了split函数

提示2:第八题中的入站流量和出站流量为,下图中的部分。且答案可以用watch来进行实时监控  

  1. # 2
  2. [root@fttswlp rough_book]# awk -F : 'NR==5 || NR==10{print NR,$1}' /etc/passwd
  3. 5 lp
  4. 10 operator
  5. # 3
  6. [root@fttswlp rough_book]# cat /etc/passwd|awk -F : '{print $(NF-1)}'
  7. # 4
  8. [root@fttswlp rough_book]# awk -F : 'NR>=5 && NR<=10{print NR,$1}' /etc/passwd
  9. # 5
  10. [root@fttswlp rough_book]# awk -F : '$7 !~ /bash/ {print NR,$7}' /etc/passwd
  11. # 6
  12. [root@fttswlp rough_book]# awk -F : 'NR ~ /5$/ {print NR,$0}' /etc/passwd
  13. # 7
  14. [root@fttswlp rough_book]# ip add|awk '/inet.*ens[0-9]+/{split($2,a,"/");print a[1]}'
  15. # 8
  16. [root@fttswlp rough_book]# ifconfig|awk 'NR==5||NR==7{print $5}' # 这个只是看那一瞬间进出站的流量大小
  17. # 若是想要实时监控每隔2秒的流量的变化,可以用下面这个命令(用watch来进行监控)
  18. [root@fttswlp rough_book]# watch -n 2 -d "ifconfig|awk 'NR==5{print $5}'"
  19. # -n,是间隔时间;-d,是看数据的差异
  20. # 9
  21. [root@fttswlp rough_book]# awk -F : 'BEGIN{i=0} /^r/{print $0;i++} END{print i}' /etc/passwd
  22. root:x:0:0:root:/root:/bin/bash
  23. 1

3.6、-F使用小技巧

若是在几个字段中结构如下所示

$1    $2:$3

我们想要截取$1和$3,若是我们直接使用awk -F "[ :]" 文件名,是找不到结果的,因为有多个空格。但若是我们这么使用awk -F "[ :]+" 文件名,那么是可以打印出来我们想要的结果的。 

4、awk命令引用shell变量问题

4.1、-v,引入shell变量

  1. [root@fttswlp ~]# name=fbb
  2. [root@fttswlp ~]# echo |awk -v sg=$name '{print sg}'
  3. fbb

4.2、使用双引号,但是$符号需要转义

注意:命令被shell解析,有些地方需要考虑转义

  1. [root@fttswlp ~]# mn=zhaoliying
  2. [root@fttswlp ~]# cat /etc/passwd|awk -F: "\$1 ~ /$mn/{print NR,\$0}"
  3. 50 zhaoliying1:x:7802:7805::/home/zhaoliying1:/bin/bash
  4. 51 zhaoliying2:x:7803:7806::/home/zhaoliying2:/bin/bash
  5. # 注意shell里面的变量($mn)不需要转义,因为它需要被shell解析;但是$1和$0需要加入转义,因为他们不要被shell进行解析。只需要awk对他们进行解析就行了。

5、awk内置函数

length

5.1、length

作用:用来统计字符的多少 

  1. # 可以用来统计用户中没有设置密码的用户数量和具体的用户。只要/etc/shadow里面第二个字段的长度小于2就表明没有设置密码。
  2. [root@fttswlp ~]# cat /etc/shadow|awk -F: 'BEGIN{i=0}length($2) <=2 {print "用户没有设置密码:"$1;i++}END{print "有"i"个用户没有设置密码"}'
  3. 用户没有设置密码:xiaohui
  4. 用户没有设置密码:tcpdump
  5. 用户没有设置密码:mysql
  6. 有40个用户没有设置密码
  1. # 显示用户名长度在5到10之间的用户,并且使用shell为bash,uid大于500
  2. [root@fttswlp ~]# cat /etc/passwd|awk -F: 'length($1)>=5 && length($1) <=10 && $3>500 && /bash$/{print $0}'
  3. chenxw:x:1004:1004::/home/chenxw:/bin/bash
  4. caohx:x:1005:1005::/home/caohx:/bin/bash
  5. zhangjian:x:1006:1006::/home/zhangjian:/bin/bash

5.2、toupper和tolower

作用:转化为大小写

  1. [root@fttswlp ~]# cat /etc/passwd|awk -F: 'length($1)>=5 && length($1) <=10 && $3>500 && /bash$/{print NR,toupper($1)}'
  2. 21 CHENXW
  3. 22 CAOHX

5.3、split

注意:用split切片出来的数组的下标,是从1开始的。

  1. [root@fttswlp ~]# cat /etc/passwd|awk -F: 'length($1)>=5 && length($1) <=10 && $3>500 && /bash$/{split($7,s,"/");print NR,s[3]}'
  2. 21 bash
  3. 22 bash

5.4、substr

作用:单独截取某个字段的单独几个字符

  1. # 选取第一个字段,只截取第一个到第四个字符
  2. [root@fttswlp ~]# cat /etc/passwd|awk -F: 'length($1)>=5 && length($1) <=10 && $3>500 && /bash$/{print NR,substr($1,1,4)}'
  3. 21 chen
  4. 22 caoh
  5. ###### substr($1,n,m):截取下标为n元素后面的m个元素(包括n)

6、流控(if和for)

6.1、if

分为单分支、双分支和多分支

6.1.1、单分支和双分支

  1. [root@fttswlp ~]# ifconfig|awk 'NR==5||NR==7{if($1 == "RX")print "接受的流量为:"$5;else print "发送的流量为:"$5}'
  2. 接受的流量为:280732
  3. 发送的流量为:218441

6.1.2、多分支

  1. # 利用awk的if多分支判断用户的类型,root显示为管理员
  2. [root@fttswlp ~]# awk -F : '{if($3==0)print $1"是管理员";else if($3>0 && $3<500) print $1"是系统用户";else if($3>=500 && $3<=60000)print $1,"是普通用户";else print $1"是其他用户"}' /etc/passwd|head -5
  3. root是管理员
  4. bin是系统用户
  5. daemon是系统用户
  6. adm是系统用户
  7. lp是系统用户
  8. #### 并统计各用户数量
  9. [root@fttswlp rough_book]# cat /etc/passwd|head -5| awk -F : '{if($3==0){print $1"是超级用户";cj++;}else if($3>0 && $3<1100) {print $1"是系统用户";xi++;}else {print $1"是普通用户";pt++}}END{print "超级用户为:"cj,"系统用户为:"xi,"普通用户为:"pt}'
  10. root是超级用户
  11. bin是系统用户
  12. daemon是系统用户
  13. adm是系统用户
  14. lp是系统用户
  15. 超级用户为:1 系统用户为:4 普通用户为:

 这个是上面那个例子的进阶版

6.1.3、总结

if语句后面执行多个命令的时候,使用{}括起来,最后的命令接;结尾。外面的else if和else前面不需要接;了。

6.2、for

格式为:

 

 

6.2.1、自增(awk的行求和)

  1. # 这里的$i,是对应的一行的列序号
  2. [root@fttswlp ~]# seq -s ' ' 10|awk '{for (i=1;i<=NF;i++) sum+=$i}END{print sum}'
  3. 55

若是列求和的话,不需要使用for循环

  1. [root@fttswlp ~]# seq 10 |awk '{sum+=$1}END{print sum}'
  2. 55

7、awk数组

作用:累加(行累加和列累加)和统计功能

shell编程中的数组,类似于python中的字典。用一个字段做key,另一个字段做value,存放数据到数组,取数据的时候使用for循环。

  1. [root@fttswlp ~]# cat /etc/passwd|awk -F: '{user[$1]=$3 }END{for (i in user) print i,user[i]}'
  2. adm 3
  3. sync 5
  4. mail 8

7.1、一列中有重复的值,但是对应的另一列的内容一直不一样,想要实现累加功能。

  1. # 该文件大致内容如下所示:
  2. [root@fttswlp linux]# cat rough_book/time/access.log
  3. 192.168.0.237 - - [18/Dec/2021:17:02:21 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"
  4. # 统计该文件中IP地址获得的流量大小。我们利用了shell数组中会自动去重的功能。
  5. # 对第二列进行降序排序
  6. [root@fttswlp linux]# cat rough_book/time/access.log|awk '{traffic[$1]+=$10}END{for (i in traffic)print i,traffic[i]}'|sort -k2 -nr
  7. 192.168.0.237 489358
  8. 192.168.0.13 482846
  9. 192.168.0.251 2340
  10. 192.168.0.7 1170
  11. 192.168.0.69 1170
  12. 192.168.0.37 1170
  13. 192.168.0.30 1170
  14. 192.168.0.208 1170
  15. 192.168.0.14 1170

 

  1. [root@fttswlp awk]# awk 'NR>1{cz[$1]+=$2}END{for (i in cz)print i,cz[i]}' gamebill.txt |sort -k2 -nr
  2. li 1329
  3. feng 650
  4. zhang 450

7.2、awk数组小练习

7.2.1、输出文本的第一行和最后一行

  1. [root@fttswlp awk]# cat /etc/passwd|awk 'NR==1{print NR,$0}END{print NR,$0}'
  2. 1 root:x:0:0:root:/root:/bin/bash
  3. 51 zhaoliying2:x:7803:7806::/home/zhaoliying2:/bin/bash

7.2.2、已知一台服务器netstat -an 输出格式如下

  1. 2:
  2. cat abc.txt|awk 'NR>1{split($5,ip,":");sc[ip[1]]+=1}END{for (i in sc)print "ip:"i,"count:"sc[i]}'|head
  3. 3.
  4. cat abc.txt|awk 'NR >1 1&& $6 ~/EST/{split($5,ip,":");sc[ip[1]]+=1}END{for (i in sc)print "ip:"i,"count:"sc[i]}'
  5. # 另外一种方法:
  6. cat abc.txt|awk 'NR > 1&& $6 ~/EST/{split($5,ip,":");print ip[1]}'|sort|uniq -c|sort -nr
  7. # 统计一下状态的数量
  8. cat abc.txt|awk 'NR>1{state[$6]+=1}END{for (i in state)print "状态为:"i,"数量为:"state[i]}'

7.2.3、计算nginx日志 

  1. 1.
  2. cat nginx.txt|awk -F "|" '{t[substr($1,1,16)]+=$6}END{for (i in t) print i,t[i]}'
  3. 2. # 思路:使用时间+url一起做key,然后统计次数
  4. cat nginx.txt|awk -F "[|?]" '{t[substr($1,1,16)$4]+=1}END{for (i in t) print i,t[i]}'

 

8、分析操作系统自带的脚本(/etc/init.d/functions和/etc/init.d/network)

这些文件在"/etc/init.d"文件夹里面

  1. [root@fttswlp rough_book]# cd /etc/init.d
  2. [root@fttswlp init.d]# ls
  3. functions netconsole network README

8.1、functions

  1. # 分析第7行到第23行
  2. 6
  3. 7 TEXTDOMAIN=initscripts # 赋值一个变量
  4. 8
  5. 9 # Make sure umask is sane
  6. 10 umask 022
  7. 11
  8. 12 # Set up a default search path.
  9. 13 PATH="/sbin:/usr/sbin:/bin:/usr/bin"
  10. 14 export PATH
  11. 15
  12. # -ne,not equal不等于;-a,and;-z,判断后面着变量的长度是否为0;最后一个"\"为续行符
  13. 16 if [ $PPID -ne 1 -a -z "$SYSTEMCTL_SKIP_REDIRECT" ] && \
  14. # -d,判断后面的路径是否为目录。
  15. 17 [ -d /run/systemd/system ] ; then
  16. # "$0",脚本文件的名字
  17. 18 case "$0" in
  18. # 如果这个脚本文件在下面的这里路径中,那么久设置_use_systemctl=1
  19. 19 /etc/init.d/*|/etc/rc.d/init.d/*)
  20. 20 _use_systemctl=1
  21. 21 ;;
  22. 22 esac
  23. 23 fi
  1. # 分析25到56行
  2. 25 systemctl_redirect () { # 定义一个函数名
  3. 26 local s
  4. 27 local prog=${1##*/} # 对第一个位置变量,从左边开始删除直到遇到最后一个/为止
  5. 28 local command=$2
  6. 29 local options=""
  7. 30
  8. 31 case "$command" in
  9. 32 start)
  10. 33 s=$"Starting $prog (via systemctl): "
  11. 34 ;;
  12. 35 stop)
  13. 36 s=$"Stopping $prog (via systemctl): "
  14. 37 ;;
  15. 38 reload|try-reload)
  16. 39 s=$"Reloading $prog configuration (via systemctl): "
  17. 40 ;;
  18. 41 restart|try-restart|condrestart)
  19. 42 s=$"Restarting $prog (via systemctl): "
  20. 43 ;;
  21. 44 esac
  22. 45
  23. # 如果这个变量不为0
  24. 46 if [ -n "$SYSTEMCTL_IGNORE_DEPENDENCIES" ] ; then
  25. 47 options="--ignore-dependencies"
  26. 48 fi
  27. 49
  28. # 如果systemctl show "$prog.service"执行没有成功,
  29. 50 if ! systemctl show "$prog.service" > /dev/null 2>&1 || \
  30. # systemctl show -p LoadState "$prog.service" | grep -q 'not-found' ,或者,这条命令没有找到,那么就执行下面的语句
  31. 51 systemctl show -p LoadState "$prog.service" | grep -q 'not-found' ; then
  32. 52 action $"Reloading systemd: " /bin/systemctl daemon-reload
  33. 53 fi
  34. 54
  35. # 这里的action是一个函数
  36. 55 action "$s" /bin/systemctl $options $command "$prog.service"
  37. 56 }
  1. 624 is_ignored_file() {
  2. 625 case "$1" in
  3. 626 *~ | *.bak | *.old | *.orig | *.rpmnew | *.rpmorig | *.rpmsave)
  4. 627 return 0
  5. 628 ;;
  6. 629 esac
  7. 630 return 1
  8. 631 }
  9. 674 for file in /usr/lib/sysctl.d/*.conf ; do
  10. # is_ignored_file,是一个函数
  11. 675 is_ignored_file "$file" && continue
  12. 676 [ -f /run/sysctl.d/${file##*/} ] && continue
  13. 677 [ -f /etc/sysctl.d/${file##*/} ] && continue
  14. # test -f,一样是判断文件是否存在
  15. 678 test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
  16. 679 done
  17. 680 for file in /run/sysctl.d/*.conf ; do
  18. 681 is_ignored_file "$file" && continue
  19. 682 [ -f /etc/sysctl.d/${file##*/} ] && continue
  20. 683 test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
  21. 684 done
  22. 685 for file in /etc/sysctl.d/*.conf ; do
  23. 686 is_ignored_file "$file" && continue
  24. 687 test -f "$file" && sysctl -e -p "$file" >/dev/null 2>&1
  25. 688 done
  26. 689 sysctl -e -p /etc/sysctl.conf >/dev/null 2>&1
  27. 690 fi
  28. 691 }

8.2、bash自带的处理字符串

  1. # a=www.bai.com
  2. [root@fttswlp ~]# echo ${#a} # 统计a中的字符个数
  3. 11
  4. [root@fttswlp ~]# echo ${a:3} # $a中从第三个开始取值到结束
  5. .bai.com
  6. [root@fttswlp ~]# echo ${a:3:2} # $a中从第三个开始取两个字符
  7. .b
  8. [root@fttswlp ~]# echo ${a: -1} # 取最后一个字符
  9. m
  10. [root@fttswlp ~]# echo ${a#*.} # 从左边开始删除直到遇到.为止
  11. bai.com
  12. [root@fttswlp ~]# echo ${a##*.} # 从左边开始删除直到遇到最后一个.为止
  13. com
  14. [root@fttswlp ~]# echo ${a%.*} # 从右边开始删除知道遇到第一个.为止
  15. www.bai
  16. [root@fttswlp ~]# echo ${a%%.*} # 从右边开始删除直到遇到最后一个.为止
  17. www
  18. [root@fttswlp ~]# echo ${a/www/hhh} # 将变量a中的第一个www替换成hhh
  19. hhh.bai.com
  20. #######
  21. [root@fttswlp ~]# a=www.www.123
  22. [root@fttswlp ~]# echo ${a//www/hhh} # 将变量a中的所有www替换成hhh
  23. hhh.hhh.123

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/115054
推荐阅读
相关标签
  

闽ICP备14008679号