- 介绍
- 基础
- 场景
- 参数
- 案例
- 添加变量,NR等于行号,$0表示一整行的内容
- 主要在于[ :],同时以空格和冒号进行了分割,更加的方便我们进行提取对应的内容
- 分隔符
- 输出的分隔符改为了’—-‘,(制表符\t)
- 变量
- 这样我们可以打印多个文件的内容,但是这个时候,awk把两个文件当成了一个整体,行号是依次递增的
- 这个时候就用到了FNR变量,可以将两个文件的行号区分开来
- 将输出的内容,用空格就作为一个新的内容,遇到空格就换行
- 在输出内容中,每一个换行符更换为新的内容
- 这个时候我们打印的时候,第一列会显示我们当前的内容是属于哪个文件的
- 这个时候打印出的内容,会先显示”我要开始用awk了”,再显示打印的具体的内容,这里是BEGIN的模块用法
- 这里面在视频当中ARGV依次显示了awk,文件名和空格,如果再加上一个文件进行同时处理的时候,发现[2]变成了第二个文件名
- 这里就是我们自己定义了一个变量myname,在之后输入的时候直接调用,打印出来的内容就是我们赋值的内容
- 或者我们可以在打印的时候直接定义,也是可以的
- 我们在终端直接赋值变量的时候,我们可以利用echo $变量,来打印变量,相应的,我们在awk定义的时候也是可以定义这个变量的
- 格式化
- 我们用printf打印出来的内容是一整行没有进行换行的
- 其实和print $0输出的内容是一样的
- 这里面有几个%d\n,就会输出几个内容,因为awk里面每个字符段都要赋值一个格式命令
- 等于给每列都加上了一个开头,再进行打印每行的内容
- awk模式pattern
- awk与正则表达式
- 一种我们可以用grep过滤
- 那么用awk我们也可以这样
- awk命令执行流程
介绍
awk是一个强大的linux命令,有强大的文本格式化的能力,好比将一些文本数据格式化成专业的excel表的样式。
awk早期在unix上实现,我们用的awk是gawk,是GUN awk的意思。
*我们利用 whic awk 可以查看awk的文件,然后利用 ls -l 查看他的具体信息,我们是可以看到他是一个指向这gawk的软连接
基础
语法:awk [option] ‘pattern[action]’ file …
awk 参数 ‘条件动作’ 文件/数据
- 打印文本的第一列
awk ‘{print $1}’ lianxi.txt
我们执行的命令是 awk ‘{print $2}’ ,没有使用参数和模式,$2 表示输出文本的第二列信息。
- awk默认以空格为分隔符,且多个空格也识别为一个空格,作为分隔符
- awk是按行处理文件,一行处理完毕,处理下一行,根据用户指定的分隔符去工作
- 指定分隔符后,awk把每一行切割后的数据对应到内置变量
- $0代表整行,1则代表第一列,以此类推
- $NF表示当前分割后的最后一列(因为nf直接代表了一行有多少字段)
- 倒数第二列可以写成($NF-1)
awk内置变量
一次输出多列信息
awk ‘{print $1,$2,$3}’ lianxi.txt awk ‘{print $1,$3,$2}’ lianxi.txt
awk是允许我们进行一次输出多列的,并且是可以定制内容信息的,顺序是由我们自己输入决定的,另外输出时我们可以利用逗号来进行隔开,不然内容是拼接在一起的。
自动定义输出内容
awk,必须外层单引号,内层双引号
内置变量$1、$2都不得添加双引号,否则会识别为文本,尽量别加引号。
awk ‘{print “第一列:”$1,”第二列:”$3,”第三列”$2}’ lianxi.txt
输出整行信息
awk ‘{print}’ lianxi.txt awk ‘{print $0}’ lianxi.txt
参数
-F 指定分割字段符
-v 定义或修改一个awk内部的变量
-f 从脚本文件中读取awk命令
案例
1.显示文件第五行
awk ‘NR==5{print $0}’ lianxi.txt
2.显示文件第2-5行
awk ‘NR==2,NR==5{print $0}’ lianxi.txt
3.给每一行的内容添加行号
添加变量,NR等于行号,$0表示一整行的内容
awk ‘{print NR,$0}’ lianxi.txt
4.显示文件第3-5行且输出行号
awk ‘NR==3,NR==5{print NR,$0}’ lianxi.txt
5.显示pwd.txt文件的第一列,倒数第二和最后一列
awk ‘{print $1,$(NF-1),$NF}’ pwd.txt
6.删除文件中的空白行
awk ‘!/^$/{print $0}’ lianxi.txt #print动作也可以不输入,效果一致
7.同时以空格和冒号作为分隔符
awk -F “[ :]” “{print $1 $2}” lianxi.txt
主要在于[ :],同时以空格和冒号进行了分割,更加的方便我们进行提取对应的内容
分隔符
awk的分隔有两种
- 输入分隔符,awk默认是空格,空白字符,英文是filed separator,变量名是FS
输出分隔符,output field separator,简称OFS
FS输入分隔符
awk逐行处理文本的时候,以输入分隔符为准,把文本切成多个片段,默认符号是空格
当我们处理特殊文件,没有空格的时候,可以自由指定分隔符awk -F “:” ‘{print $1}’ lianxi.txt #更改为了以冒号为分隔符
除了使用-F选项,还可以使用变量的形式,指定分隔符,使用-v选项搭配,修改FS变量,效果一样
awk -v FS=”:” ‘{print $1}’ lianxi.txt
OFS输出分隔符
awk执行完命令,默认用空格隔开每一列,这个空格就是awk的默认输出符
输出的分隔符改为了’—-‘,(制表符\t)
awk -F “:” -v OFS==”—-“ ‘{print $1}’ lianxi.txt
变量
- 内置变量
- 自定义变量
内置变量
NR、NF、FNR
- awk的内置变量NR、NF是不用添加$符号的
- 而$0 $1 $2 …是需要添加$符号的
这样我们可以打印多个文件的内容,但是这个时候,awk把两个文件当成了一个整体,行号是依次递增的
awk ‘{print NR,$0}’ lianxi1.txt lianxi2.txt
这个时候就用到了FNR变量,可以将两个文件的行号区分开来
awk ‘{print FNR,$0}’ lianxi1.txt lianxi2.txt
RS、ORS
ORS是输出分隔符的意思,awk默认认为,每一行结束了,就得添加回车换行符
ORS变量可以更改输出符
将输出的内容,用空格就作为一个新的内容,遇到空格就换行
awk -v RS==’ ‘ ‘{print NR,$0}’ lianxi1.txt
在输出内容中,每一个换行符更换为新的内容
awk -v ORS==’@’ ‘{print NR,$0}’ lianxi1.txt
FILENAME
显示awk正在处理文件的名字
这个时候我们打印的时候,第一列会显示我们当前的内容是属于哪个文件的
awk ‘{print FILENAME,FNR,$0}’ lianxi1.txt lianxi2.txt
ARGC、ARGV
ARGV表示的是一个数组,数组中保存的是命令行所给的参数
数组是一种数据类型,如同一个盒子
盒子有它的名字,且内部有N个小格子,标号从0开始
这个时候打印出的内容,会先显示”我要开始用awk了”,再显示打印的具体的内容,这里是BEGIN的模块用法
awk ‘BEGIN{print “我要开始用awk了”} {print $0}’ lianxi.txt
这里面在视频当中ARGV依次显示了awk,文件名和空格,如果再加上一个文件进行同时处理的时候,发现[2]变成了第二个文件名
awk ‘BEGIN{print “我要开始用awk了”} {print ARGV[0],ARGV[1],ARGV[2]}’ lianxi.txt
自定义变量
顾名思义,就是我们自己定义变量
- 方法一:-v varName=value
- 方法二:在程序中直接定义
- 方法三:间接引用shell脚本
方法一:
这里就是我们自己定义了一个变量myname,在之后输入的时候直接调用,打印出来的内容就是我们赋值的内容
awk -v myname=”dzc” ‘BEGIN{print myname}’ 方法二:
或者我们可以在打印的时候直接定义,也是可以的
awk ‘BEGIN{print myname=”dzc”}’ 方法三:
我们在终端直接赋值变量的时候,我们可以利用echo $变量,来打印变量,相应的,我们在awk定义的时候也是可以定义这个变量的
dzc=”hahaha” echo $dzc —> hahaha awk -v myname=$dzc ‘BEGIN{print myname}’ —> hahaha
格式化
前面我们接触到的awk输出功能,是{print}的功能,只能对文本简单的输出,并不能美化或者修改格式。
printf格式化输出
在c语言和go语言当中,printf()函数也是文本格式化输出。(我没用过,,,就学过Python的print输出功能T.T)
printf和print的区别
- 其与print命令的最大不同是,printf需要指定format
- format用于指定后面的每个item的输出格式
-
format的使用
format格式的指示符都是以%开头,后跟一个字符:
%c:显示字符的ASCII码
%d,%i:十进制整数
%e,%E:科学计数法显示数值
%f:显示浮点数
%g,%G:以科学计数法的格式或浮点数的格式显示数值
%s:显示字符串
%u:无符号整数
%%:即%本身printf修饰符:
-:左对齐,默认右对齐
+:显示数值符号,printf “%+d” printf 动作默认不会添加换行符
- print 默认添加空格换行符
我们用printf打印出来的内容是一整行没有进行换行的
awk ‘{printf $0}’ lianxi.txt
printf不同格式用法
1.分行输出
其实和print $0输出的内容是一样的
awk ‘{printf “%s\n”,$0}’ lianxi.txt
2.多个变量
这里面有几个%d\n,就会输出几个内容,因为awk里面每个字符段都要赋值一个格式命令
awk ‘BEGIN{print “%d\n%d\n%d\n”,1,2,3}’
3.如果是一个文本
等于给每列都加上了一个开头,再进行打印每行的内容
awk ‘{printf “第一列:%s 第二列:%s 第三列:%s\n”,$1,$2,$3}’ lianxi.txt
4.制作一个较为完善容易观看的表类型
awk ‘BEGIN{printf “%-10s\t %-10s\t %-10\n”,”姓名”,”学号”,”成绩”} {printf “%-10s\t %-10s\t %-10s\n”,$1,$2,$3}’ 9lianxi.txt
%s\t 格式化字符串后,添加制表符,四个空格(别忘了最后要换成\n,因为要换行了)
%-25s 依旧是格式化字符串内容,-代表左对齐,25代表25个字符长度
awk模式pattern
关于 BEGIN 和 END 的具体解析,也是两种pattern的模式:
- BEGIN模式是处理文本之前需要执行的操作
- END模式是处理完所有行之后执行的操作
在之前的操作里面,BEGIN已经有了初步的了解,大致也就如此,而END也就是相反,一个开头输入,一个结尾输入
而模式我们也可以理解为是条件,awk默认是按行处理文本的,如果不指定任何模式(条件),awk默认一行行处理,如果指定了模式(条件),只有符合模式的才会被处理
- 关于运算符,==、<、>、!=、~…之类的
awk与正则表达式
正则表达式主要与awk的pattern模式(条件)结合使用
- 不指定模式,awk每一行都会执行对应的动作
- 指定了模式,只有被模式匹配到的、符合条件的行才回执行动作
- 找出pwd.txt中以games开头的行
一种我们可以用grep过滤
grep ‘^games’ pwd.txt
那么用awk我们也可以这样
awk ‘/^games/{print $0}’ pwd.txt
语法:
grep ‘正则表达式’ pwd.txt
awk ‘/正则表达式/动作’ /etc/passwd
awk命令使用正则表达式,必须把正则放入“//”双斜杠中,匹配到结果后执行动作(print $0),打印整行信息。
当然awk能做到的还有更多,就好像awk功能更高级,但不代表他不能干低级的事情,虽然可能相比较grep繁琐一些,但是awk能做到的其他事情也是grep远远不能比肩的。
awk命令执行流程
解读:假如我们要从pwd.txt文件中,读取我们想要的需求内容
awk ‘BEGIN{ command } pattern{ command }END{ command }’ pwd.txt
- 优先我执行BEGIN{}模式中的语句
- 从pwd.txt文件中读取第一行,然后执行pattern{ command }进行正则匹配,如:/^n/寻找n开头的行,找到了执行{ print }进行打印
- 当awk读取到文件数据流的结尾时,会执行END{ command }
