linux中awk的使用
参考文献:https://www.cnblogs.com/jiqianqian/p/7944013.html
awk是一个强大的文本分析工具。相较于sed常常一整行处理,awk则倾向于将一行数据切片,分成数个“字段”处理;简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
语法:
awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
awk [options] 'pattern{action}' file
1.查看最近5条登录用户和ip地址
awk工作流程是这样的:读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,所以1表示登录用户,$3表示登录用户ip,以此类推。
$ last -n 2|awk '{print $1"\t"$3}' lzyer 192.168.56.1 reboot boot
$ last -n 2|awk '{print $1,$3}' lzyer 192.168.56.1 reboot boot
只处理第一行的数据
$ last -n 2|awk 'NR==1{print $1,$3}' lzyer 192.168.56.1
2.print和printf
参考:https://www.cnblogs.com/soymilk2019/p/12165545.html
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数用来格式化字符串,输出复杂时,printf更加好用,代码更易懂。
1. 使用printf输出的文本不会换行,如果需要换行,可以在对应的“格式替换符”后加入“\n”进行转义
2. 使用printf输出时,“指定的格式”与“被格式化的文本”之间,要用“,”隔开
3. 使用printf输出时,“格式”中的“格式替换符”必须与“被格式化的文本”一一对应(个数要相同)
eg:
1.#awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
输出:filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash 2.awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
输出:filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
转义字符
|
定义
|
修饰符
|
定义
|
c
|
字符
|
-
|
左对齐修饰符
|
s
|
字符串
|
#
|
显示8 进制整数时在前面加个0
显示16 进制整数时在前面加0x
|
d
|
十进制整数
|
+
|
显示使用d 、e 、f 和g 转换的整数时,加上正负号+或-
|
ld
|
十进制长整数
|
0
|
用0而不是空白符来填充所显示的值
|
u
|
十进制无符号整数
|
格式说明符
|
功能
|
lu
|
十进制无符号长整数
|
%c
|
打印单个ASCII 字符
printf("The character is %c\n",x) 输出: The character is A
|
x
|
十六进制整数
|
%d
|
打印一个十进制数
printf("The boy is %d years old\n",y) 输出:The boy is 15 years old
|
lx
|
十六进制长整数
|
%e
|
打印数字的e 记数法形式
printf("z is %e\n",z) 打印: z is 2.3e+0 1
|
o
|
八进制整数
|
%f
|
打印一个浮点数
printf("z is %f\n", 2.3 * 2) 输出: z is 4.600000
|
lo
|
八进制长整数
|
%o
|
打印数字的八进制
printf("y is %o\n",y) 输出:z is 17
|
e
|
用科学记数法(e 记数法)表示的浮点数
|
%s
|
打印一个字符串
print("The name of the culprit is %s\n",$1) 输出:The name of the culprit is Bob Smith
|
f
|
浮点数
|
%x
|
打印数字的十六进制值
printf("y is %x\n",y) 输出:x is f
|
g
|
选用e或f中较短的一种形式
|
3.正则匹配
搜索/etc/passwd有root关键字的所有行
awk -F: '/root/' /etc/passwd 输出:root:x:0:0:root:/root:/bin/bash
这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。
搜索/etc/passwd有root关键字的所有行,并显示对应的shell,这里指定了action{print $7}
awk -F: '/root/{print $7}' /etc/passwd
输出:/bin/bash
awk '$4 ~/Technology/' employee.txt
操作符〜是正则表达式比较。如果匹配的默认操作,即打印整行.
4.awk内置变量
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
5.常见用法
1. -F指定分隔符,默认为空格
awk -F: 'NR==1{print}' /etc/passwd root:x:0:0:root:/root:/bin/bash
2. -v 替换变量
var1=100 echo |awk -v var=$var1 '{print var}' 100
3.使用内置变量FS指定输入分隔符,需要注意的是,使用变量时,要使用-v选项来指定对应的变量
awk -v FS=":" 'NR==1{print}' /etc/passwd root:x:0:0:root:/root:/bin/bash awk -v FS=":" -v OFS="#" 'NR==1{print $1,$2}' /etc/passwd root#x
指定多个分隔符[]
[root@cxm ~]# cat 123 1111111111*222222222222222|33333333333#4444444444444&5555555555555555 #根据上边的文件,我们可以以* |#& 为分隔符 [root@cxm ~]# awk -F '[*|#&]' '{print $3}' 123 33333333333 [root@cxm ~]# awk -F '[*|#&]' '{print $4}' 123 4444444444444
2.连续的分隔符为一个分隔符
[root@cxm ~]# cat 222 111111*****2222222|||||||3333333########444444444&&&&&&&&&55555555 #在[]后边加个+(加号) [root@cxm ~]# awk -F '[*|#&]+' '{print $3}' 222 3333333 #默认连续不同的分隔符也会成为一个分隔符 [root@cxm ~]# cat 333 111111*|2222222|||||||3333333########444444444&&&&&&&&&55555555 [root@cxm ~]# awk -F '[*|#&]+' '{print $3}' 333 3333333 #*和|变成了一个分隔符
BEGIN、END 的使用
$ awk 'BEGIN {print "Name\tDesignation\tDepartment\tSalary";} > {print $2,"\t",$3,"\t",$4,"\t",$NF;} > END{print "Report Generated\n--------------";}' employee.txt
2.计算整个文档的第四个字段中包含Technology字符串的行数
awk 'BEGIN {count=0;} $4 ~ /Technology/ {count++;} END {print "the number =",count;}' test_awk.txt
6. 关系运算符
关系运算符 | 含义 | 用法实例 |
< | 小于 | x<y |
<= | 小于等于 | x<=y |
> | 大于 | x>y |
>= | 大于等于 | x>=y |
== | 等于 | x==y |
!= | 不等于 | x!=y |
~ | 匹配 | x~/正则表达式/ |
!~ | 不匹配 | x!~/正则表达式/ |
7.其他栗子
awk '{print "\""}' #使用“”双引号把一个双引号括起来,然后用转义字符\对双引号进行转义,输出双引号。
输出单引号:
awk '{print "'\''"}' # 使用一个双引号“”,然后在双引号里面加入两个单引号‘’,接着在两个单引号里面加入一个转义的单引号\',输出单引号。
8.awk 同时处理两行
处理第一行的时候,NR=1,NR%2!=0,执行了后面的a=$1,a=1
处理第二行的时候,NR%2==0,执行print a","$1"d"打印出来a和本行$1,即1,3d。再处理就是个循环过程。
9.删除指定行
从</root>行删除到最后行 sed -i '/<\/root>/d' a.xml
从第一行删除到<root>行 sed -i '/<root>/d' a.xml