Linux基础最终篇 三剑客的熟练运用

三剑客

grep

  • 作用:过滤内容的行
-n 打印关键字并显示在第几行
例:[root@web02 ~]# grep -n 1 cd.sh 
3:    for ((i = 0 ; i <= 100 ; i+=15)); do

-A 打印过滤内容后n行
# 例:-A3
-B 打印过滤内容前n行
# 例:-B2
-C 打印过滤内容前后n行
# 例:-C4
     #A B C 必须加数字

-E (过滤多个内容)支持正则
    过滤多个的时候用|去分隔
     # 关键字|关键字
    # 需要用管道符隔开
    过滤掉以#和空行
例:[root@web02 ~]# grep -E 'root|mysql' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin

-w 以单词形式精准匹配
例:[root@web02 ~]# grep -w 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

-o 打印关键字
[root@web02 ~]# grep -o 'root' /etc/passwd
root
root
root
root

-v 取反
例:[root@web02 ~]# grep -v 'root' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
redis:x:997:995:Redis Database Server:/var/lib/redis:/sbin/nologin
tomcat:x:53:53:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

-i 不区分大小写
例:[root@web02 ~]# grep -i 'd' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
redis:x:997:995:Redis Database Server:/var/lib/redis:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

-q 静默输出(不显示)

-c 显示过滤内容的多少行的数量
例:[root@web02 ~]# grep -c 'd' /etc/passwd
13

-l 查看过滤内容是否在所过滤文件之中(对比关键字在哪个文件之中)
例:[root@web02 ~]# grep -l 'd' /etc/passwd
/etc/passwd

例;[root@web02 ~]# grep -l 'mail' /etc/passwd tiaoban.sh 
/etc/passwd

-L 过滤不包含所查内容的文件(对比关键字不在哪个文件)
例:[root@web02 ~]# grep -L 'mail' /etc/passwd tiaoban.sh 
tiaoban.sh

-r 递归检索文件(精准不能使用通配符)
例:[root@web02 ~]# grep -r 'mail' ./
./passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

-h 只显示文件内容
例:[root@web02 ~]# grep -hr 'mail' ./
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

-f 对比文件内容(只过滤相同的内容)

-vf 才是对比文件内容(过滤不相同内容)

-F 带关键字的内容以列表展示
例:[root@web02 ~]# grep -F aaa 1.txt 2.txt 
1.txt:aaa 
2.txt:aaa 

-m 显示n行过滤内容
例:[root@web02 ~]# grep -m 5 '1' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

-x 只显示完全匹配的行(全部关键字符合)
[root@web02 ~]# grep -x 'ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

-R 进行递归搜索。在指定的目录及其子目录中搜索匹配的文件。
grep -R "pattern" directory
例:[root@web02 ~]# grep -R 'mail' ./
./passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

sed

sed针对核心内容
增
删
改
查

sed命令的执行流程

-n 匹配你要的内容
不加-n 匹配你要的内容和全部内容

1.sed先是按行读取文件内容
2.每读取一行内容,都会进行一次判断,是不是你想要的行
3.如果不是,则判断是不是加了-n选项
4.如果加了-n,就读取下一行
5.如果没加-n,就会将所有内容输出到命令行(默认输出)
6.如果是,你想要的那一行(第三行)则判断执行的后续动作(p d s a i c)
7.动作处理完成后,输出指定的内容
8.即便是读取完了,内容也输出了,sed也会继续往后读,直到文件的最后一行

d:删除匹配指定模式的行。
p:打印匹配指定模式的行。
i:在指定行前插入文本。
a:在指定行后追加文本。

-n: 取消默认输出
-p: 打印                                                                    

# 打印所有行并再打印第二行
[root@web02 ~]# sed '2p' lll.txt 
1,wyd,666
2,hhh,777
2,hhh,777
3,wb,888
4,zdp,999

# 打印第二行
[root@web02 ~]# sed -n '2p' lll.txt 
2,hhh,777

# 打印所有行并再打印第一行到第三行
[root@web02 ~]# sed '1,3p' lll.txt 
1,wyd,666 
1,wyd,666
2,hhh,777
2,hhh,777
3,wb,888
3,wb,888
4,zdp,999

# 打印所有行并再打印第一行和第三行
[root@web02 ~]# sed '1p;3p' lll.txt 
1,wyd,666
1,wyd,666
2,hhh,777
3,wb,888
3,wb,888
4,zdp,999

# 模糊匹配
[root@web02 ~]# sed -n '/y/p' lll.txt
1,wyd,666
[root@web02 ~]# sed -n '/,/p' lll.txt
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999
[root@web02 ~]# sed -n '/6/p' lll.txt
1,wyd,666

#模糊查询
[root@web02 ~]# sed -n '/6/p;/7/p' lll.txt
1,wyd,666
2,hhh,777

# 范围模糊查找
[root@web02 ~]# sed -n '/wyd/,/wb/p' lll.txt
1,wyd,666
2,hhh,777
3,wb,888

# sed模拟grep -A
[root@web02 ~]# sed -n '/wyd/,+2p' lll.txt
1,wyd,666
2,hhh,777
3,wb,888

# 模拟seq
[root@web02 ~]# seq 1 2 10
1
3
5
7
9

[root@web02 ~]# sed -n '1~3p' lll.txt 
1,wyd,666
4,zdp,999
[root@web02 ~]# sed -n '1~2p' lll.txt 
1,wyd,666
3,wb,888

# 取反
[root@web02 ~]# sed -n '/wyd/!p' lll.txt 
2,hhh,777
3,wb,888
4,zdp,999

d: delete 删除

# 临时删除
[root@web02 ~]# sed '2d' lll.txt
1,wyd,666
3,wb,888
4,zdp,999
[root@web02 ~]# cat lll.txt 
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999

# 永久删除
[root@web02 ~]# sed -i '2d' lll.txt
[root@web02 ~]# cat lll.txt 
1,wyd,666
3,wb,888
4,zdp,999

# 删除第一行
[root@web02 ~]# sed '1d' lll.txt 
3,wb,888
4,zdp,999

# 删除最后一行
[root@web02 ~]# sed '$d' lll.txt 
1,wyd,666
3,wb,888

# 删除第一行以外的所有行
[root@web02 ~]# sed '1!d' lll.txt 
1,wyd,666

# 删除包含hhh到最后一行
[root@web02 ~]# sed '/hhh/,$d' lll.txt 
1,wyd,666

# 删除wb到yl的行
[root@web02 ~]# sed '/wb/,/yl/d' lll.txt 
1,wyd,666
2,hhh,777

cai
a: 在最后一行追加
i: 在前插入
c: 替换整行内容
---------------------------------------------------

# 在最后一行加入新的行
[root@web02 ~]# sed '$a6,ljy,111' lll.txt 
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999
5,yl,000
6,ljy,111

# 在第二行下加入新的行
[root@web02 ~]# sed '2a6,ljy,111' lll.txt 
1,wyd,666
2,hhh,777
6,ljy,111
3,wb,888
4,zdp,999
5,yl,000

#i insert 在前面插入
[root@web02 ~]# sed '$i6,ljy,111' lll.txt 
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999
6,ljy,111
5,yl,000

#c 替换整行内容
[root@web02 ~]# sed '$c6,ljy,111' lll.txt 
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999
6,ljy,111

s substitute 替换
g global     全局(如果去掉全局替换则只替换第一个匹配到的)

s###g
s///g
s@@@g

[root@web02 ~]# cat lll.txt |sed s#666#000#g
1,wyd,000
2,hhh,777
3,wb,888
4,zdp,999
5,yl,000

[root@web02 ~]# cat lll.txt |sed s#999#123#g
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,123
5,yl,000

# 正则 (每个数字都变成666)
[root@web02 ~]# cat lll.txt |sed 's#[0-9]#666#g'
666,wyd,666666666
666,hhh,666666666
666,wb,666666666
666,zdp,666666666
666,yl,666666666

使用后项引用截取IP

[root@web02 ~]# ifconfig |sed -n '2p'|sed -r 's#inet (10.0.0.8)  netmask 255.255.255.0  broadcast 10.0.0.255#\1#g'
        10.0.0.8

[root@web02 ~]# ifconfig eth0| sed -nr 's#^.*inet (.*)  net.*#\1#gp'
10.0.0.8

模式空间

[root@web02 ~]# sed 'N;s#\n# #g' lll.txt 
1,wyd,666 2,hhh,777
3,wb,888 4,zdp,999
5,yl,000
`N` 命令读取下一行到模式空间中,然后将当前行和下一行合并。
`s#\n# #g` 命令将合并后的行中的换行符替换为空格。
`lll.txt` 是要处理的源文件。

# 如果要把文件都换成一行,有多少行加多少N
[root@web02 ~]# sed 'N;N;N;N;s#\n# #g' lll.txt
1,wyd,666 2,hhh,777 3,wb,888 4,zdp,999 5,yl,000

# 使用sed循环语句实现把所有行变为一行上
[root@web02 ~]# sed ':label;N;s#\n# #g;t label' lll.txt 
1,wyd,666 2,hhh,777 3,wb,888 4,zdp,999 5,yl,000

awk

  • awk也能做for循环

  • awk有单引 双引之分

    '' 输出变量
    "" 输出字符串
    
    awk输出变量用单引号 bash输出变量用双引号
  • awk又交做GNU awk,gawk

    [root@zabbix01 ~]# ls -l which awk
    lrwxrwxrwx. 1 root root 4 6月 12 10:58 /usr/bin/awk -> gawk
  • awk不是一个命令,是一门语言

    平时我们使用,都是当做命令使用,所以我们称之为 单行脚本

    那么awk能不能写脚本呢,必然可以,在linux系统中就有很多的jawk脚本

    [root@web02 ~]# find /usr/share/ -type f -name '*.awk'
    /usr/share/awk/assert.awk
    /usr/share/awk/bits2str.awk
    /usr/share/awk/cliff_rand.awk
    /usr/share/awk/ctime.awk
    /usr/share/awk/ftrans.awk
    /usr/share/awk/getopt.awk
    /usr/share/awk/gettime.awk
    /usr/share/awk/group.awk
    /usr/share/awk/join.awk
    /usr/share/awk/libintl.awk
    /usr/share/awk/noassign.awk
    /usr/share/awk/ord.awk
    /usr/share/awk/passwd.awk
    /usr/share/awk/quicksort.awk
    /usr/share/awk/readable.awk
    /usr/share/awk/rewind.awk
    /usr/share/awk/round.awk
    /usr/share/awk/strtonum.awk
    /usr/share/awk/walkarray.awk
    /usr/share/awk/zerofile.awk

awk执行流程

# 读取文件之前
1.读取文件之前先看 命令的选项 -F -v
-F 指定分隔符
-v 赋予变量
2.如果写了BEGIN 执行BEGIN的动作

BEGIN{}
[root@web02 ~]# awk 'BEGIN{print 1+3}'
4

# 读取文件时
1.读取文件 一行一行去读
读取第一行 判断是否满足条件,如果是就执行对应的动作
    {print $1}如果满足就打印
    开始读文件 第一行符合
    看分隔符是不是
    然后打印第一行
    再读取第下一行
    再打印
如果条件不满足 awk会继续读取下一行,直到条件满足或文件的最后一行

{}
[root@web02 ~]# awk '{print 1+3}' 1.txt
4
4

# 读取文件之后
所有文件读取完成之后,走END{}中的指令
END{}
[root@web02 ~]# awk 'END{print 1+3}' 1.txt
4

[root@web02 ~]# awk '{print $0}END{print 1/3}' lll.txt
1,wyd,666
2,hhh,777
3,wb,888
4,zdp,999
5,yl,000
0.333333

# 结合读取文件之前 读取文件之时 读取文件之后
[root@web02 ~]# awk -F : 'BEGIN{print "name","uid"}{print $1,$3}END{print "文件处理完成"}' /etc/passwd |column -t
name             uid
root             0
bin              1
daemon           2
adm              3
lp               4
sync             5
shutdown         6
halt             7
mail             8
operator         11
games            12
ftp              14
nobody           99
systemd-network  192
dbus             81
polkitd          999
sshd             74
postfix          89
nginx            998
apache           48
mysql            27
rpc              32
redis            997
tomcat           53
rpcuser          29
nfsnobody        65534
文件处理完成
  • awk读取文件内容之前

    1.读取文件之前,先看命令的选项,例如 -F,-v

    2.如果写了BEGIN{}则先在BEGIN{}中的指令

  • awk读取文件内容之时

    1.awk在读取文件时,也是一行一行的读

    2.读取一行之后,判断是否满足条件,如果是,则执行{对应动作}

    • {print $1}
    • awk -F , {print $1} 1.txt
  • 3.如果不满足条件,awk继续读取下一行,直到满足条件或者到文件的最后一行

  • awk读取文件内容之后

    1.所有文件读取完成之后,走END{}中的指令

awk的行和列

行 记录 record
列 字段 field

取行

# NR
number of record

NR==1
[root@web02 ~]# awk 'NR==1' /etc/passwd
root:x:0:0:root:/root:/bin/bash

# 取第一行到第三行
[root@web02 ~]# awk 'NR<=3' /etc/passwd
[root@web02 ~]# awk 'NR==1,NR==3' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# sed取第三行到最后一行
[root@web02 ~]# sed -n '3,$p' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
redis:x:997:995:Redis Database Server:/var/lib/redis:/sbin/nologin
tomcat:x:53:53:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

# awk取第三行到最后一行
[root@web02 ~]# awk 'NR>=3' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
redis:x:997:995:Redis Database Server:/var/lib/redis:/sbin/nologin
tomcat:x:53:53:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

awk -vRS=,
# 以, 为换行符 默认是以回车为分隔符 
[root@web02 web02]# cat 1.txt
1,wyd,666
2.hhh.777
3,wb,888
4.zdp.999
5,msx,000
[root@web02 web02]# awk -vRS=, "NR==2" 1.txt
wyd
[root@web02 web02]# awk -vRS=, "NR==3" 1.txt
666
2.hhh.777
3
[root@web02 web02]# awk -vRS=, "NR==4" 1.txt
wb
[root@web02 web02]# awk -vRS=, "NR==5" 1.txt
888
4.zdp.999
5

[root@web02 ~]# awk -vRS=, '{print "这里是行号:"NR,"这里是每一行的内容:"$0}' 1.txt
这里是行号:1 这里是每一行的内容:1
这里是行号:2 这里是每一行的内容:wyd
这里是行号:3 这里是每一行的内容:666 2
这里是行号:4 这里是每一行的内容:hhh
这里是行号:5 这里是每一行的内容:777 3
这里是行号:6 这里是每一行的内容:wb
这里是行号:7 这里是每一行的内容:888 4
这里是行号:8 这里是每一行的内容:zdp
这里是行号:9 这里是每一行的内容:999
5
这里是行号:10 这里是每一行的内容:yl
这里是行号:11 这里是每一行的内容:000

1,wyd,666 2,hhh,777 3,wb,888 4,zdp,999
5,yl,000

取列 取字段

-vFS=:
-F :
FS 列分隔符

$数字 /$内容

NF==$number of field

FS: 内置变量 列分隔符 -F: = -vFS=:
[root@web02 ~]# awk -vFS=: '{print $1,$NF}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
sshd /sbin/nologin
postfix /sbin/nologin
nginx /sbin/nologin
apache /sbin/nologin
mysql /sbin/nologin
rpc /sbin/nologin
redis /sbin/nologin
tomcat /sbin/nologin
rpcuser /sbin/nologin
nfsnobody /sbin/nologin

## 以字符串分隔将空格替换成#
[root@web02 ~]# awk -F: '{print $1"#"$2"#"$NF}' /etc/passwd
root#x#/bin/bash
bin#x#/sbin/nologin
daemon#x#/sbin/nologin
adm#x#/sbin/nologin
lp#x#/sbin/nologin
sync#x#/bin/sync
shutdown#x#/sbin/shutdown
halt#x#/sbin/halt
mail#x#/sbin/nologin
operator#x#/sbin/nologin
games#x#/sbin/nologin
ftp#x#/sbin/nologin
nobody#x#/sbin/nologin
systemd-network#x#/sbin/nologin
dbus#x#/sbin/nologin
polkitd#x#/sbin/nologin
sshd#x#/sbin/nologin
postfix#x#/sbin/nologin
nginx#x#/sbin/nologin
apache#x#/sbin/nologin
mysql#x#/sbin/nologin
rpc#x#/sbin/nologin
redis#x#/sbin/nologin
tomcat#x#/sbin/nologin
rpcuser#x#/sbin/nologin
nfsnobody#x#/sbin/nologin

## 修改输出后的内容分隔符
-vOFS=
[root@web02 ~]# awk -F: -vOFS=\| '{print $1,$2,$3,$4,$5}' /etc/passwd
root|x|0|0|root
bin|x|1|1|bin
daemon|x|2|2|daemon
adm|x|3|4|adm
lp|x|4|7|lp
sync|x|5|0|sync
shutdown|x|6|0|shutdown
halt|x|7|0|halt
mail|x|8|12|mail
operator|x|11|0|operator
games|x|12|100|games
ftp|x|14|50|FTP User
nobody|x|99|99|Nobody
systemd-network|x|192|192|systemd Network Management
dbus|x|81|81|System message bus
polkitd|x|999|998|User for polkitd
sshd|x|74|74|Privilege-separated SSH
postfix|x|89|89|
nginx|x|998|996|Nginx web server
apache|x|48|48|Apache
mysql|x|27|27|MariaDB Server
rpc|x|32|32|Rpcbind Daemon
redis|x|997|995|Redis Database Server
tomcat|x|53|53|Apache Tomcat
rpcuser|x|29|29|RPC Service User
nfsnobody|x|65534|65534|Anonymous NFS User

awk的取行列

[root@web02 ~]# top -n1|awk 'NR==1{print $3}'
10:04:38

[root@web02 ~]# top -n1 |awk 'NR>=7{print $12}'
TIME+
0:00.74
0:00.00
0:00.09
0:00.00
0:00.00
0:00.00
0:00.31
0:00.00
0:00.03
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:00.02
0:00.00
0:00.00
0:00.00
0:00.00

[root@web02 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 |awk -F '"' 'NR==11{print $2}'
10.0.0.8
## 把姓氏为Zhang的人,他们第二次捐款数量的数据和姓名
# 解答1
[root@web02 ~]# cat 1.txt | awk 'NR==3;NR==8'|awk '{print $1,$2,$4}'|awk -F ':' '{print $1,$3}'
Zhang Xinyu  300
Zhang Yuqi  290
# 解答2
[root@web02 ~]# awk -F '[ :]+' 'BEGIN{print  "姓名","捐款数额"} /^Zhang/{print $1,$2,$5}' 1.txt 
姓名 捐款数额
Zhang Xinyu 300
Zhang Yuqi 290

## 显示所有以25开头的qq号码和姓名
# 解答1
[root@web02 ~]# awk '$3 ~ /^25/{print $1,$2,$3}' 1.txt 
Di Lireba 253097001
Wen Zhang 259872003
# 解答2
[root@web02 ~]# cat 1.txt|awk 'NR==5;NR==9'|awk '{print $1,$2,$3}'
Di Lireba 253097001
Wen Zhang 259872003

## 显示所有QQ号最后一位是1/3的人 姓名和QQ
# 解答1
[root@web02 ~]# awk '$3 ~ /(1|3)$/{print $1,$2,$3}' 1.txt 
Zeng Laoshi 133411023
Deng Ziqi 44002231
Di Lireba 253097001
Wen Zhang 259872003
# 解答2
[root@web02 ~]# cat 1.txt|awk 'NR==1;NR==2;NR==5;NR==9'|awk '{print $1,$2,$3}'
Zeng Laoshi 133411023
Deng Ziqi 44002231
Di Lireba 253097001
Wen Zhang 259872003

## 捐款显示$为分隔符
# 解答1
[root@web02 ~]# awk '{gsub(/:/,"$");print $0}' 1.txt
Zeng Laoshi       133411023        $110$100$75
Deng Ziqi            44002231        $250$10$88
Zhang Xinyu      877623568      $120$300$200
Gu Linazha         11029987         $120$30$79
Di Lireba             253097001      $220$100$200
Jiang Shuying    535432779       $309$10$2
Ju Jingyi             68005178         $130$280$385
Zhang Yuqi         376788757       $500$290$33
Wen Zhang         259872003      $100$200$300
gsub("被替换的内容","替换的内容",第N列)
# 解答2
[root@web02 ~]# cat 1.txt|awk -F : -vOFS=$ '{print $1,$2,$3,$4}'
Zeng Laoshi       133411023        $110$100$75
Deng Ziqi            44002231        $250$10$88
Zhang Xinyu      877623568      $120$300$200
Gu Linazha         11029987         $120$30$79
Di Lireba             253097001      $220$100$200
Jiang Shuying    535432779       $309$10$2
Ju Jingyi             68005178         $130$280$385
Zhang Yuqi         376788757       $500$290$33
Wen Zhang         259872003      $100$200$300

## 显示ifconfig中 范围是1~255的数字
# 解答
$0表示整行内容
[root@web02 ~]# ifconfig | awk -vRS='[^0-9]' '$0>=1 && $0<=255'
10
8
255
255
255
10
255
6
80
20
29
7
6
64
20
29
7
6
2
1
172
16
1
8
255
255
255
172
16
1
255
6
80
20
29
7
64
20
29
7
11
73
127
1
255
6
1
128
10

awk模式与动作

模式

在awk中到底有哪些可以被看做是模式的呢?

  • 正则表达式

    # 正则表达式写法
    '/正则表达式/flag'
    '$1~/正则表达式/flag'
    '$1!~/正则表达式/flag'
    只不过我们在awk中很少使用flag
  • 比较表达式

    NR==1
    NR>=10
    NR<=100
    NR>=1 && NR<=10
    $1>=100
  • 范围模式

    ## 精确匹配行号:从第10行到第20行
    NR==10,NR==20
    NR>=10&&NR<=20
    ## 精确匹配字符串:从该字符串的行到另一个字符串所在行
    '/root/,/zls/'
    '/从哪个字符串所在行/,/到那个字符串所在行/' #中间的行都包含进去
    ## 模糊匹配字符串:从含有该字符串所在行到含有另一字符串所在行
    '$1~/oo/,$1~/zl/

动作

在awk中,我们最常用的动作就是 print

当然我们还有别的动作可以使用:

  • print打印
  • gsub替换
  • 变量赋值
  • 统计计算

BEGIN模式

如果要使用BEGIN模式,那么一定要成双成对的出现: BEGIN{}

那么我们要知道,BEGIN{}中,大括号里面的内容,会在读取文件内容之前执行

主要应用场景:

  • 1.统计或计算
[root@zabbix01 ~]# awk 'BEGIN{print 1/3}'
0.333333
  • 2.awk功能测试
  • 3.输出表格的表头

END模式

一般来说,END{}要比BEGIN{}重要一些,BEGIN{}可有可无,计算其实可以放在读取文件的时候,也可

以执行

END{}中,大括号里面的内容,会在awk读取完文件的最后一行后,进行处理

作用:一般我们使用END{}来显示对日志内容分析后的一个结果

当然,还有其他功能,比如文件读取完了,可以显示一些尾部信息

# 1.统计/etc/service文件中一共有多少行
## 分析:
## 条件:无
## 动作:读一行就加1 {i++}

[root@zabbix01 ~]# awk '{i++;print i}' /etc/services
#这么写是读一行会加一次,读一行会加一次,把整个过程都显示出来了。

#我么现在只需要显示一个结果,所以我们需要把print放到END{}中

## 传统写法
[root@zabbix01 ~]# awk '{i++}END{print i}' /etc/services
11176

## 流氓写法
[root@zabbix01 ~]# sed -n '$=' /etc/services
11176

# 2.统计/etc/service中空行的数量
[root@zabbix01 ~]# awk '/^$/{i++}END{print i}' /etc/services
17

# 3.统计出下列文件中所有人的年龄和
[root@zabbix01 ~]# vim student.txt
姓名 年龄
曾老湿 23
苍颈空 18
西冶详 99

[root@zabbix01 ~]# awk 'NR>1{i=i+$2}END{print i}' student.txt
140

[root@zabbix01 ~]# awk 'NR>1{i+=$2}END{print i}' student.txt
140

# 4.统计nginx日志中,状态码是200的次数以及,状态码是200时占用的流量
条件:
- 获取状态码 $9
- 获取大小 /流量 $10

## 获取条件
awk '$10==200' blog.driverzeng.com_access.log

## 执行动作
awk '$10==200{i++;count=count+$11}END{print i,count}' blog.driverzeng.com_access.log
848 112743579

# 美化
awk '$10==200{i++;count=count+$11}END{print "正常状态码次数:"i,"总流量(字节):"count}' blog.driverzeng.com_access.log
正常状态码次数:848 总流量(字节):112743579

## 脚本写法
awk '
$10==200{
    i++;
    count=count+$11
}
END{
    print "正常状态码次数:"i,"总流量(字节):"count }' blog.driverzeng.com_access.log

# 5.统计nginx日志中状态码是4xx和5xx的次数及总流量
条件:以4,5开头
动作:统计总流量
awk '$10~/^[45]/{i++;count+=$11}END{print i,count}'
blog.driverzeng.com_access.log

## 那么2xx的3xx的
awk '$10~/^2/{i++;count+=$11}END{print i,count}' blog.driverzeng.com_access.log
awk '$10~/^3/{i++;count+=$11}END{print i,count}' blog.driverzeng.com_access.log

# 6.综合应用:分别统计每种状态码的总流量
## 最简单的写法
awk '
$10~/^2/{i2++;count2+=$11}
$10~/^3/{i3++;count3+=$11}
$10~/^4/{i4++;count4+=$11}
$10~/^5/{i5++;count5+=$11}
END{
print "2xx状态码:",i2,count2
print "3xx状态码:",i3,count3
print "4xx状态码:",i4,count4
print "5xx状态码:",i5,count5 }' blog.driverzeng.com_access.log
### 注意:这种方式并不好,所以我们需要使用awk更牛逼的方法来统计不同分类的,比如统计IP,统计URI就没有

数组

赋值

awk 'BEGIN{array[0]="wyd";array[1]='hhh'}'

取值

awk 'BEGIN{array[0]="wyd";array[1]="hhh";print array[0],array[1]}'

数组

[root@web02 ~]# awk 'BEGIN{array[0]="zls";array[1]="cls";
> for(name in array){
>    print name
>  }}'
0
1
[root@web02 ~]# awk 'BEGIN{array[0]="zls";array[1]="cls";
for(name in array){
   print array[name]
 }}'
zls
cls
#1.取出下列域名并根据域名,进行统计排序处理
https://blog.driverzeng.com/index.html
https://blog.driverzeng.com/1.html
http://post.driverzeng.com/index.html
http://mp3.driverzeng.com/index.html
https://blog.driverzeng.com/3.html
http://post.driverzeng.com/2.html

## 在awk中,我们给数组赋值,肯定不能像上面那样赋值
#正确赋值方式:
array[]++

# 让数组的下标自增,然后在中括号中写入要统计的内容
array[域名所在列]++
array[$3]++ #当然这个$3是以/为分隔符

[root@zabbix01 ~]# awk -F/ '{url[$3]++}END{for(n in url){print n,url[n]}}'
url.txt
blog.driverzeng.com 3
post.driverzeng.com 2
mp3.driverzeng.com 1

#2.统计nginx日志中,每个IP访问使用的流量总和
条件:无
动作:统计IP及流量总和 array[$1]=array[$1]+$11 可以写成ip[$1]+=$11

awk '{array[$1]+=$11}END{for(ip in array){print ip,array[ip]}}'
blog.driverzeng.com_access.log

#3.每个IP出现的次数及使用的流量
条件:无
动作:
1.统计ip的次数:count[$1]++
2.流量总和:sum[$1]+=$11
awk '{count[$1]++;num[$1]+=$11}END{for(ip in count){print ip,count[ip],num[ip]}}' blog.driverzeng.com_access.log

awk判断-if

#1.单分支判断
if($1~/root/){
    print $1,$2
}

#2.双分支判断
if(){
}else{
}
if(){
}else if(){
}else{
}

awk循环-for

# 数组专用循环
for(n in array){
    print n,array[n]
}

# 通用循环
for(i=1;i<10;i++){
    print i
}
#2.企业面试题:统计每个学生的总成绩和平均成绩
stu01 70 80 90 100 90 80
stu02 89 78 98 67 97 90
stu03 56 12 33 44 55 66 77
stu04 89 78 77 99 100 30
stu05 98 97 96 95 94 93
stu06 100 20 20 20 20 20
[root@web02 ~]# awk '{sum = 0; for (i = 2; i <= NF; i++) sum += $i; avg = sum / (NF - 1); print $1, "总成绩:", sum, "平均成绩:", avg}' jisuan.txt 
stu01 总成绩: 510 平均成绩: 85
stu02 总成绩: 519 平均成绩: 86.5
stu03 总成绩: 343 平均成绩: 49
stu04 总成绩: 473 平均成绩: 78.8333
stu05 总成绩: 573 平均成绩: 95.5
stu06 总成绩: 200 平均成绩: 33.3333

# 在awk中定义了要执行的代码块
{sum = 0; for (i = 2; i <= NF; i++) sum += $i; avg = sum / (NF - 1); print $1, "总成绩:", sum, "平均成绩:", avg}

# 创建一个变量sum设置初始值为0,保存总成绩
sum = 0

# 使用循环 i=2 代表从第二列开始 i <= NF 代表当前列到最后一行时停止循环 i++ 自增 sum += 
for (i = 2; i <= NF; i++) sum += $i # 所有成绩加算到sum中

# 计算平均成绩 avg是变量 = sum 总成绩 / 除以 (NF - 1)表示总列数减去学生名
avg = sum / (NF - 1)

# 打印学生名字
print $1

# 打印"总成绩:" 后打印sum(总成绩)
"总成绩:", sum

# 打印"平均成绩:" 后打印avg(平均成绩)
"平均成绩:", avg
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇