#!/bin/bash
# END{} 统计计算
#
# 统计方法 简写形式 应用场景
# i=i+1 i++ 计数,统计次数
# sum=sum+??? sum+=??? 求和,累加
#
# sum;i 都是变量可以随便设置
# 统计/etc/services 中的空行数量
cat /etc/services | wc -l
awk '/^$/{i++}END{print i}' /etc/services
#统计 /etc/ssh/ssh_config 中以#开头的行 的数量
awk '/^#/{i++}END{print i}' /etc/ssh/ssh_config
#计算1+..100(awk)
[root@localhost ~] seq 1 100 | awk '{i+=$1}END{print i}'
5050
# awk自己定义数组之分开取值
[root@localhost ~]# awk 'BEGIN{a[0]=123;a[1]="test";print a[0],a[1]}'
123 test
# awk自己定义数组取出awk中的所有数组的值
# for (i in a) 将数组的下标赋值给i 取数值中的值写为 a[i]
[root@localhost ~]# awk 'BEGIN{a[0]="test1";a[1]="test2";a[2]="test3";a[3]="test5";for(i in a) print i}'
0
1
2
3
[root@localhost ~]# awk 'BEGIN{a[0]="test1";a[1]="test2";a[2]="test3";a[3]="test5";for(i in a) print a[i]}'
test1
test2
test3
test5
#处理以下文件内容,将域名取出并根据域名进行计数排序处理
# http://www.etiantian.org/index.htm1
# http://www.etiantian.org/1.htm1
# http://post.etiantian.org/index.htm1
# http://mp3.etiantian.org/index.htm1
# http://www.etiantian.org/3.htm1
# http://post.etiantian.org/2.htm1
[root@localhost ~]# cat url.txt | awk -F"[/.]+" '{a[$2]++}END{for(i in a)print i,a[i]}' | sort -nrk2 | column -t
www 3
post 2
mp3 1
#面试题:统计这段语句中,单词中字符数小于6的单词,显示出来.
#echo "I am oldboy teacher welcome to oldboy training class."
[root@localhost ~]# echo "I am oldboy teacher welcome to oldboy training class." | awk '{for(i=1;i<=NF;i++) if(length($i)<=6) print $i}'
I
am
oldboy
to
oldboy
class.
#=====注意awk注意;的使用=====
#用awk计算1+..100的结果
[root@localhost ~]# awk 'BEGIN{sum=0;for(i=1;i<=100;i++) sum+=i ;print sum}'
5050
#用awk取列取8列到最后一列 (多行! jar包ps检查多行)
# root 1294 1 17 21:32 pts/0 00:00:07 java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
# root 1342 1 32 21:32 pts/0 00:00:06 java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
# root 1373 1 74 21:32 pts/0 00:00:06 java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
[root@localhost opt]# ps -ef |grep jar | grep -v grep | awk '{for(i=8;i<=NF;i++)printf $i" ";print ""}'
java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
java -jar -Xms128M -Xmx512M /opt/test.jar --server.port=1111
#用awk取列取3列到第6列 (for循环对列的进行循环处理 3为起始;<=控制最终列;NF为最后一列)
[root@localhost opt]# ps -ef |grep jar | grep -v grep | awk '{for(i=3;i<=6;i++)printf $i" ";print ""}'
1 3 21:32 pts/0
1 3 21:32 pts/0
1 3 21:32 pts/0
#用awk取出磁盘(已用%)大于10的 磁盘名字 使用率 挂载点等信息
# 文件系统 容量 已用 可用 已用% 挂载点
# devtmpfs 475M 0 475M 0% /dev
# tmpfs 487M 0 487M 0% /dev/shm
# tmpfs 487M 7.5M 479M 2% /run
# tmpfs 487M 0 487M 0% /sys/fs/cgroup
# /dev/mapper/centos-root 27G 2.0G 26G 8% /
# /dev/sda1 1014M 168M 847M 17% /boot
# tmpfs 98M 0 98M 0% /run/user/0
[root@localhost ~] df -h | awk -F"[ %]+" 'BEGIN{print "磁盘名字","使用率","挂载点"}/^\/dev/{if($5>10) print$1,$(NF-1),$NF}' | column -t
磁盘名字 使用率 挂载点
/dev/sda1 17 /boot
# 需求取出最近登录的ip和用户 不要 'hecs-103465' 'sshd[16011]:' 这两列 -> 不要第4列和第5列
[root@localhost ~] cat /var/log/secure |grep "Accepted"
Feb 26 18:40:52 hecs-103465 sshd[16011]: Accepted password for root from 183.226.117.240 port 3547 ssh2
Feb 26 19:08:11 hecs-103465 sshd[16243]: Accepted password for root from 183.226.117.240 port 3254 ssh2
Feb 26 20:24:37 hecs-103465 sshd[16812]: Accepted password for root from 172.104.115.240 port 47220 ssh2
Feb 26 21:40:58 hecs-103465 sshd[17186]: Accepted password for root from 183.226.117.240 port 3140 ssh2
Feb 26 22:08:54 hecs-103465 sshd[17359]: Accepted password for root from 183.226.117.240 port 3181 ssh2
# 解决方案
# 使用awk的列切割功能来实现,例如: awk '{for(i=1;i<=NF;i++)if(i<=2||i>=5) print $i}' file.txt,这条命令会将文件file.txt中的前两列和第五列以后的内容打印出来。
[root@localhost ~] cat /var/log/secure |grep "Accepted"|awk '{for(i=1;i<=NF;i++)if(i<=3||i>=6)printf $i" ";print " "}'
Feb 26 18:40:52 Accepted password for root from 183.226.117.240 port 3547 ssh2
Feb 26 19:08:11 Accepted password for root from 183.226.117.240 port 3254 ssh2
Feb 26 20:24:37 Accepted password for root from 172.104.115.240 port 47220 ssh2
Feb 26 21:40:58 Accepted password for root from 183.226.117.240 port 3140 ssh2
Feb 26 22:08:54 Accepted password for root from 183.226.117.240 port 3181 ssh2
Feb 27 13:05:47 Accepted publickey for root from 59.2.141.160 port 52798 ssh2: RSA SHA256:P7d7T+VjNzuXTCwthIGsHiGgQitbY3FoKL3M8qRJOg4
# shell 统计匹配出了多少行 如果内容大于10行则只输出10行
# 可以使用管道符号将命令传递给 awk 命令,使用变量计数匹配行数,并使用 if 语句限制输出到前 10 行。示例:
grep "pattern" file.txt | awk 'BEGIN {count=0} {count++; if (count<=10) print} END {if (count>10) print count " lines matched."}'
这将从 file.txt 中查找匹配 "pattern" 的行,并输出前 10 行。如果匹配的行数大于 10 行,则最后一行会输出匹配的行数和 "lines matched." 的消息。
# sed 给第一行快速添加命令解释器
sed '1i #!/bin/bash' filename
#先匹配cat的行 进行字串替换 #\1 为在第一个括号的内容前添加#
[ansible_user1@hecs-103465 ~]$ sed '/cat/s/\(.*\)/#\1/g' 1.sh -i
# 使用sed修改文件后缀名字
sed -r 's/.[a-z]+$/.log/g' #将任意后缀名修改为.log
# awk取出第六列不包含127的行
[root@VM-0-16-centos ~]# netstat -n|grep 'ESTABLISHED$' |awk '$5 !~ /127/{print}'
tcp 0 0 172.30.0.16:38900 169.254.0.55:5574 ESTABLISHED
tcp 0 0 172.30.0.16:51096 169.254.0.138:8186 ESTABLISHED
tcp 0 184 172.30.0.16:53580 123.144.20.142:51794 ESTABLISHED
tcp 0 0 172.30.0.16:38902 169.254.0.55:5574 ESTABLISHED
tcp6 0 0 172.30.0.16:53814 139.186.141.106:16670 ESTABLISHED
tcp6 0 17 172.30.0.16:19902 172.30.0.16:51198 ESTABLISHED
tcp6 0 0 172.30.0.16:51198 172.30.0.16:19902 ESTABLISHED
#去除没有注释和非空的行
awk '!/^#/&&!/^$/{print}' nginx.conf
#awk取出以tcp开头的行中第五列不包含127和172的行
netstat -n |awk '/^tcp/{if($5 !~ 127 && $5 !~ 172 )print}'
#快速注释以ipv6开头的行
cat ifcfg-ens32 | sed -r 's/(^IPV6.*)/#\1/g'
# 需求取出最近登录的ip和用户 不要 'hecs-103465' 'sshd[16011]:' 这两列 -> 不要第4列和第5列
[root@localhost ~] cat /var/log/secure |grep "Accepted"
Feb 26 18:40:52 hecs-103465 sshd[16011]: Accepted password for root from 183.226.117.240 port 3547 ssh2
Feb 26 19:08:11 hecs-103465 sshd[16243]: Accepted password for root from 183.226.117.240 port 3254 ssh2
Feb 26 20:24:37 hecs-103465 sshd[16812]: Accepted password for root from 172.104.115.240 port 47220 ssh2
Feb 26 21:40:58 hecs-103465 sshd[17186]: Accepted password for root from 183.226.117.240 port 3140 ssh2
Feb 26 22:08:54 hecs-103465 sshd[17359]: Accepted password for root from 183.226.117.240 port 3181 ssh2
# 解决方案
# 使用awk的列切割功能来实现,例如: awk '{for(i=1;i<=NF;i++)if(i<=2||i>=5) print $i}' file.txt,这条命令会将文件file.txt中的前两列和第五列以后的内容打印出来。
[root@localhost ~] cat /var/log/secure |grep "Accepted"|awk '{for(i=1;i<=NF;i++)if(i<=3||i>=6)printf $i" ";print " "}'
Feb 26 18:40:52 Accepted password for root from 183.226.117.240 port 3547 ssh2
Feb 26 19:08:11 Accepted password for root from 183.226.117.240 port 3254 ssh2
Feb 26 20:24:37 Accepted password for root from 172.104.115.240 port 47220 ssh2
Feb 26 21:40:58 Accepted password for root from 183.226.117.240 port 3140 ssh2
Feb 26 22:08:54 Accepted password for root from 183.226.117.240 port 3181 ssh2
Feb 27 13:05:47 Accepted publickey for root from 59.2.141.160 port 52798 ssh2: RSA SHA256:P7d7T+VjNzuXTCwthIGsHiGgQitbY3FoKL3M8qRJOg4
# shell 统计匹配出了多少行 如果内容大于10行则只输出10行
# 可以使用管道符号将命令传递给 awk 命令,使用变量计数匹配行数,并使用 if 语句限制输出到前 10 行。示例:
grep "pattern" file.txt | awk 'BEGIN {count=0} {count++; if (count<=10) print} END {if (count>10) print count " lines matched."}'
这将从 file.txt 中查找匹配 "pattern" 的行,并输出前 10 行。如果匹配的行数大于 10 行,则最后一行会输出匹配的行数和 "lines matched." 的消息。
# sed 给第一行快速添加命令解释器
sed '1i #!/bin/bash' filename
#先匹配cat的行 进行字串替换 #\1 为在第一个括号的内容前添加#
[ansible_user1@hecs-103465 ~]$ sed '/cat/s/\(.*\)/#\1/g' 1.sh -i
# 使用sed修改文件后缀名字
sed -r 's/.[a-z]+$/.log/g' #将任意后缀名修改为.log
# awk取出第六列不包含127的行
[root@VM-0-16-centos ~]# netstat -n|grep 'ESTABLISHED$' |awk '$5 !~ /127/{print}'
tcp 0 0 172.30.0.16:38900 169.254.0.55:5574 ESTABLISHED
tcp 0 0 172.30.0.16:51096 169.254.0.138:8186 ESTABLISHED
tcp 0 184 172.30.0.16:53580 123.144.20.142:51794 ESTABLISHED
tcp 0 0 172.30.0.16:38902 169.254.0.55:5574 ESTABLISHED
tcp6 0 0 172.30.0.16:53814 139.186.141.106:16670 ESTABLISHED
tcp6 0 17 172.30.0.16:19902 172.30.0.16:51198 ESTABLISHED
tcp6 0 0 172.30.0.16:51198 172.30.0.16:19902 ESTABLISHED
#去除没有注释和非空的行
awk '!/^#/&&!/^$/{print}' nginx.conf
#awk取出以tcp开头的行中第五列不包含127和172的行
netstat -n |awk '/^tcp/{if($5 !~ 127 && $5 !~ 172 )print}'
#快速注释以ipv6开头的行
sed -r 's/(^IPV6.*)/#\1/g' ifcfg-ens32