-三剑客之 awk
1、什么是awk,主要作用是什么?
主要用来处理文本,将文本按照指定格式输出
多数处理列
2、awk的格式
1.awk [参数] '匹配规则、处理规则' [处理文本路径]
[root@localhost ~]
必须是''号
$1:代表第一列, $2:第二列 一次类推 $0:代表每次读取的行
[root@localhost ~]
NF:倒数第一列 NF-1:倒数第二列 要加() NF-2:倒数第三列 要加()
匹配规则主要是正则表达式 可以不写 直接执行处理规则包括如下:
字符串
正则表达式
处理规则设置变量、设置数组、数组循环、+-*/等一系列操作包括如下:
BEGIN{} :awk处理文件之前执行 所有变量定义都应该放在BEGIN里面
// :读取文件之后使用的匹配规则
{} :循环,每次处理一行
NED{} :awk处理文件之后执行
2.流式输出也叫(标准输出) | awk [参数] '匹配规则、处理规则'
[root@localhost ~]
案例:
案例1:把/etc/passwd中的包含root的行打印出来
[root@localhost ~]
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
案例2:把/etc/passwd中以root开头的行打印出来
[root@localhost ~]
root:x:0:0:root:/root:/bin/bash
案例3:将/etc/passwd中匹配第三列和第五列的数据
[root@localhost ~]
0 root
1 bin
2 daemon
3 adm
4 lp
5 sync
6 shutdown
案例4:打印以root或者ftp开头的行的解析器
[root@localhost ~]
/bin/bash
/sbin/nologin
---------------------------------或者
[root@localhost ~]
/bin/bash
/sbin/nologin
3、awk的工作原理
1.awk一行一行读取 处理文件,用$0来接收,换行符是分别行的符号 ,
awk -F: '{print $0}' /etc passwd
没行读取玩都放在$0里面,然后输出,等同于打印全部
2.刚才读入的行,看是否通过F 或者FS 指定分隔符,如果没指定,则使用默认分隔符'空格'来分割成若干字段或(域)
3.print 函数打印 , 里面如果想输出第一列 ,第三列 中间加个','号,这个和awk内置变量OFS一样, OFS默认为空格,于是输出 第一列和第三列中间有个空格 ,如不加逗号则输出第一列和第三列紧挨着
4.输出之后 在从文件获取下一行赋值给$0 重复2步骤分割字段,重复3 步骤执行处理规则,一直重复 直到最后一行
4、awk中的变量
$0 :当前行内容
NR :行号
NF :列数,字段
FS :输入字段分隔符 默认空格 等同于-F
OFS :输出字段分隔符,默认空格 和逗号相等,
案例:
案例1:输出/etc/passwd中的所有内容包括行号。
[root@localhost ~]
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
案例2:要求把第7行之后的内容输出出来,包括行号。
[root@localhost ~]
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
案例3:要求输出第7行之后的内容且第14行之前的内容输出出来,包含行号
[root@localhost ~]
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
案例4:由案例3,要求输出每行的UID增加1
[root@localhost ~]
7 8
8 9
11 12
12 13
14 15
99 100
案例5:要求输出倒数第3列
[root@localhost ~]
root
bin
daemon
adm
案例6:要求不使用-F参数,以:分割,并输出第3列和第5列
[root@localhost ~]
0 root
1 bin
2 daemon
3 adm
案例7:要求实验证明-F 和 FS的优先级
证明FS优先级高于-F
[root@localhost ~]
bin root:x:0:0:root:
sbin bin:x:1:1:bin:
sbin daemon:x:2:2:daemon:
案例8:要求以:分割,并输出第3列和第5列,第三列和第五列之间使用+号分割
[root@localhost ~]
0+root
1+bin
2+daemon
3+adm
4+lp
5+sync
6+shutdown
案例9:取出/etc/passwd文件中以“:”为分隔符,第三列(用户UID)以0结尾的用户?
[root@localhost tmp]
root:x:0:0:root:/root:/bin/bash
test:x:1000:1000::/home/test:/bin/bash
~代表模糊匹配 包含什么什么
0$ 以什么什么(0)结束
5、格式化输出
printf
%s 字符类型
%d 数值类型整数
-左对齐 默认右对齐 占15空格 %-d %-4d 不管有没有都占四个字符
printf不会在行尾自动换行 ,要记得加\n
案例1:要求输出第1列和最后一列,排版整齐
[root@localhost ~]
第一列: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
6、操作模式
正则模式 | awk -F: ‘/正则表达式/’ /etc/passwd |
比较模式 |
awk -F: ‘NR>7’ /etc/passwd > < 输出其行之后 |
条件模式 |
awk -F: ‘NR>7’ /etc/passwd |
算数运算 |
awk -F: ‘{print $3,$3+1}’ /etc/passwd |
范围模式 |
awk -F: ‘/root/ ,/ftp/’ /etc/passwd 输出root到ftp的行 |
7、流程控制
if
单分支 if(){}
双分支 if() {} else {}
多分支 if () {} else if() {} else {}
案例:
案例1:打印奇数行的数据
[root@localhost ~]
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
案例2:打印偶数行的数据
[root@localhost ~]
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
8 halt:x:7:0:halt:/sbin:/sbin/halt
10 operator:x:11:0:operator:/root:/sbin/nologin
注:单分支情况下是可以省略if,多分支情况下不能省略
案例3:要求打印出偶数行中的包含bash的行
[root@localhost ~]
24 test:x:996:995::/home/test:/bin/bash
26 test111:x:1001:1001::/home/test111:/bin/bash
------------------------------------------------------------------------
[root@localhost ~]
24 test:x:996:995::/home/test:/bin/bash
26 test111:x:1001:1001::/home/test111:/bin/bash
案例4:要求在奇数行前输出奇数,偶数行前输出偶数
[root@localhost ~]
奇数:root:x:0:0:root:/root:/bin/bash
偶数: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
偶数:operator:x:11:0:operator:/root:/sbin/nologin
奇数:games:x:12:100:games:/usr/games:/sbin/nologin
案例5:在前7行前加7, 前14行前加14,其他原样输出
[root@localhost ~]
for
for (变量 in 数组) {语句}
for (变量;条件;表达式){语句}
案例:
案例1:将/etc/nginx/nginx.conf中的所有的词的个数
[root@localhost ~]
案例2:要求统计以
[root@localhost ~]
案例3:输入一个文件路径,要求打印出它的数字权限(不允许使用stat)
[root@localhost ~]