0%

[linux] 6.awk指令--linux三剑客boss

江湖传言linux有三剑客, 而awk 是三剑客的老大。利剑出鞘,潜龙升天。#

introduction#

awk属于 一种编程语言,可以通过编程实现各种需要的文本处理需求。awk在其对 数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件 逐行的读入,以 空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

awk工作流程:#

读入有 ''换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域(原记录),\(1**表示**第一个域**,\)n表示第n个域。默认域分隔符是 空白键 或 tab键**。

基本用法:#

1
awk [选项参数] 'BEGIN{命令 } pattern{ 命令 } END{ 命令 }'  文件名    # 行匹配语句 awk '' 只能用单引号

pattern模块#

打印某几列#

1
2
$ echo 'i am so busy' | awk '{print $1, $2 $3}'
i amso

选项参数#

-F参数:指定分隔符

1
2
3
4
5
$ echo '192.168.1.1' | awk -F "." '{print $2}'
168

$ echo 'I am leo。my qq is xxxxxx' |awk -F '[ ,]+' '{print $3" "$7}' # 多个分隔符
leo xxxxxx
- 我们将字符串 i am so busy 通过管道传递给awk命令,相当于awk处理一个文件,该文件的内容就是i am so busy,默认通过空格作为分隔符(不管列之间有多少个空格都将当作一个空格处理)i am so busy就分割成四列了。 - 另外,我们发现pattern{ 命令 }中","输出时为空格" "。

BEGIN 定义表头#

1
2
3
4
5
6
7
8
9
10
11
$ cat score.txt
tom 60 60 60
kitty 90 95 87
jack 72 84 99

$ awk 'BEGIN{print "姓名 语文 数学 英语"}{printf "%-8s%-5d%-5d%-5d\n",$1,$2,$3,$4}' score.txt # 左对齐的操作(%-8s左对齐,宽8位)

姓名 语文数学英语
tom 60 60 60
kitty 90 95 87
jack 72 84 99

END#

1
2
3
4
5
6
7
8
9
10
11
12
$ awk 'BEGIN{print "姓名 语文 数学 英语 总成绩"; \
sum1=0;sum2=0;sum3=0;sumall=0} \ # 这里定义了初始值
{printf "%5s%5d%5d%5d%5d\n",$1,$2,$3,$4,$2+$3+$4;\
sum1+=$2;sum2+=$3;sum3+=$4;sumall+=$2+$3+$4}\
END{printf "%5s%5d%5d%5d%5d\n","总成绩",sum1,sum2,sum3,sumall}'\
score.txt

姓名 语文 数学 英语 总成绩
tom 60 60 60 180
kitty 90 95 87 272
jack 72 84 99 255
总成绩 222 239 246 707

运算符#

运算符 作用
= += -= *= /= %= ^= **= 赋值
?: C条件表达式
&& 逻辑与
~ 和 !~ 匹配正则表达式和不匹配正则表达式
< <= > >= != == 关系运算符
空格 连接
+ - 加,减
* / % 乘,除与求余
+ - ! 一元加,减和逻辑非
^ *** 求幂
++ -- 增加或减少,作为前缀或后缀
$ 字段引用
in 数组成员
example1:过滤第一列大于2的行#
1
2
3
4
5
$ awk '$1>2' log.txt    #命令
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo

exmple2:输出奇数行#

1
2
3
4
5
6
7
8
9
10
11
$ vim demo.txt
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

$ awk -F ':' 'NR % 2 == 1 {print $1}' demo.txt
root
bin
sync

exmple3:输出第一个字段等于指定值的行#

1
2
3
4
5
6
$ awk -F ':' '$1 == "root" {print $1}' demo.txt
root

$ awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' demo.txt
root
bin

if语句#

example1:善用if else判断语句#
1
2
3
4
5
6
$ awk '{if($2>=90 )print $0}' score.txt
kitty 90 95 87
$ awk '{if($2>=90 )print $1,"优秀"; else print $1,"良好"}' score.txt
tom 良好
kitty 优秀
jack 良好

内置变量#

常用内置变量:

  • FILENAME: 用于保存输入文件名称,当前文件名
  • NF: 一条记录的 字段的数目
  • NR:已经读出的记录数,就是 行号从1开始
  • OFS:用于设置输出分隔字符字符,默认空格。
  • FS:字段分隔符(默认是任何空格)。
  • ORS:用于设置输出记录分隔符,默认为新的一行。
  • RS:记录分隔符(默认是一个换行符)。
  • OFMT:数字的输出格式(默认值是%.6g)。
  • ENVIRON:读取环境变量。
example1:只查看test.txt文件第20到第30行#
1
$ awk '{if(NR>=20 && NR<=30) print $0}' test.txt 

example2:保留小数点后两位#

1
2
$ awk 'BEGIN{OFMT="%.2f";print 1.2567,12E-2}'
1.26 0.12

输出倒数第二个字段#

变量 NF表示当前行有多少个字段,因此 \(NF**就代表 **最后一个字段**。 **\)(NF-1)代表 倒数第二个字段

1
2
3
4
5
6
$ awk -F ':' '{print $1, $(NF-1)}' demo.txt
root /root
daemon /usr/sbin
bin /bin
sys /dev
sync /bin

reference#

1.awk 详解 2.ILinux三剑客传 | 老大:AWK 3.awk 入门教程