awk:文本三剑客之一,是功能最强大的文本工具
awk也是按行来进行操作,对行操作完之后,可以根据指定命令来对行取列
awk的分隔符,默认分隔符是空格或tab键,多个空格会压缩成一个
awk的用法
awk的格式:awk 选项 '模式或条件{操作}' 文件 在awk中操作默认就是打印
模式或条件:这么干 操作:操作结果 文件:操作的对象
例:打印第一列
awk '{print $1}' test.txt
$0打印全部内容
awk '{print $1,$2,$3}' test.txt
常用选项:
-F:指定分隔符,如果是空格,不需要加
-v:变量赋值(用的少)
awk常用的内置变量:
$0:打印所有的内容
$n(n为数字):处理行的第n列
NR:处理行的行号
NF:处理当前行的字段个数 $NF:表示最后一个字段
FS:列分隔符,指定文本的分隔符,和F作用一致 格式 FS=":"
不常用的:OFS输出文本的分隔符
RS:行分隔符,指定分隔符为回车
除了内置变量$n,其他的内置变量不用加$,不能用引号,也不能用括号,否则会被当成字符串处理
awk的打印功能:
awk '{print}' test.txt 打印所有,默认就是1
awk '0{print}' 什么都不打印
awk '{print NR}' test.txt 只打印行号
awk '{print NR,$0}' test.txt 既显示行号也显示内容
指定打印第三行 awk 'NR==3{print}' test.txt
打印第二行到第四行 awk 'NR==2,NR==4{print}' test.txt
奇偶打印:awk 'NR%2==0{print}' test.txt 打印偶数行
awk 'NR%2==1{print}' test.txt 打印奇数行
awk的运算功能:awk 'BEGIN{print 10+20}'
也支持小数运算 3**2或3^2 求幂即次方
面试题:awk的内置函数:getline
1、如果getline左右没有重定向符号(>,<) 或者没有管道符是,awk会先读第一行,但是如果加了getline,会跳过第一行,去读第二行
例:awk '{getline;print}' test.txt 只打印第二行和第四行,跳过了第一行和第三行
相当于打印奇数行
2、如果两边有重定向或管道符,getline作用于定向输入文件
例:awk '{getline < "test1.txt";print > "test2.txt"}' test1.txt
先从test1获取test1的内容输入到test2,作用对象为test1
3、管道符
例:ls | awk '{getline ky30;print $0,ky30;}'
ky30为自定义变量
ls输出的结果传给ky30,打印ls命令的输出结果
如果没有结果,打印空,不做如何操作
awk作为文本过滤进行打印
打印以root开头的 awk '/^root/{print}' test.txt
BEGIN模式更复杂的操作
awk 'BEGIN{..};{..};END{..}' 文件
在对文件进行操作之前,会先执行BEGIN{..}模式条件或命令操作
中间的{..}是真正的用于处理文件的命令
END{..}结束语句,一般都是打印执行结果
面试题:如何通过awk获取文件里有多少行
awk 'BEGIN{i=0};{i+1};END{print i}' test.txt
意思为test.txt有多少行就打印多少次
了解即可:-v 变量赋值,指的是改变分隔符
例:把分隔符:换成@
awk -v FS=":" -v OFS="2" '{print $1,$3}' /etc/passwd
awk的条件判断打印:
awk -F:'$3>10{print}' /etc/passwd | head -n 15 把passwd第三列大于10的全打印出来
取反 awk -F: '($4<10){print}' /etc/passwd | head -n 15 把第四列除了大于10的都打印出来
awk支持条件判断语句
awk -F:'{if ($3=10) {print}}' /etc/passwd 打印第三列等于10的内容
三元表达式:类似于JAVA 面试会问
格式:awk '(条件表达式)?(A表达式或值):(B表达式或值)'
?相当于if :相当于else
例:awk -F:'{i=($3>$4)?$3:$4;{print;}' /etc/passwd
如果满足第三列大于第四列就打印第三列,不满足就打印第四列
awk的精确筛选:>,<,= 比较数值
比较字符串:
$n~ "字符串":表示第n个字段包含某个字符串
$n!~ "字符串":表示不包含某个字符
$n== "字符串":表示第n个字符串就是某个字符
$n!= "字符串":表示不是某个字符串的选出来
$NF:表示最后一个字段
例:awk -F:'$7~"bash" {print $1,$NF}' /etc/passwd
打印第七个字段包含bash的第一例和最后一列
awk -F:'$7~"nologin" {print $1,$3}' /etc/passwd
第七个字段不是nologin,打印第一和第三个字段
awk -F:'($6=="home/dn")&&($7=="/bin/bash"){print $1,$NF}'
指定第六个字段为/home/dn 而且第七个字段是/bin/bash
&&相当于而且
awk -F:'($3!=0)||($4>10) {print $1}' /etc/passwd
所有第三列不是0或者第四列大于10的结果,打印第一列
awk结合数组来进行使用
在awk中怎么来定义数组
awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;for(i in a)print i , a[i]}'
取的是a的索引 i in的是a的索引 0,1,2是a的索引
去重统计
awk '{a[$1]++};END{for(i in a)}{print i,a[i]}' test.txt
提取host.txt主机名后再放回host.txt文件
awk -F '[ .]+' '{print $2}' ms.txt