awk
Posted whatislinux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了awk相关的知识,希望对你有一定的参考价值。
awk 独立的编程语言
Awk是一种处理结构数据并输出格式化结果的编程语言, Awk 是其作者 "Aho,Weinberger,Kernighan" 的简称。
Awk通常被用来进行格式扫描和处理。通过扫描一个或多个文件中的行,查看是否匹配指定的正则表达式,并执行相关的操作。
Awk的主要特性包含:
- Awk以记录和字段的方式来查看文本文件
- 和其他编程语言一样,Awk 包含变量、条件和循环
- Awk能够进行运算和字符串操作
- Awk能够生成格式化的报表数据
Awk从一个文件或者标准输入中读取数据,并输出结果到标准输出中。
1 awk功能2 awk的命令格式
格式一:
awk 选项 ‘处理动作’ 文件列表
格式二:
命令 | awk 选项 ‘处理动作’
3 awk对数据的处理方式
以行为单位对数据逐行处理,处理完当前行后自动处理下一行,直到处理完所有的行为止,默认把对数据处理的结果输出到屏幕。
4 选项
-F “分隔符” 指定分隔时使用的分隔符,默认列的分隔符为空格(至少一个)或tab,使用默认分隔符是可以省略
5 内置变量
5.1 2 n
(使用字段分隔符后,对应列(域)的值)
打印某一列:
awk –F”:” ‘{print $1}’ /etc/passwd
打印某几列:
(若想打印多列时用,逗号分隔)
awk –F”:” ‘{print 3,$4}’ /etc/passwd
应用:IP地址的获取。
[email protected]:/home/whatispython/workspace/shell/sed# ifconfig | sed -n ‘/inet /p‘ | awk -F" " ‘{print 2}‘
172.16.126.252
127.0.0.1
[email protected]:/home/whatispython/workspace/shell/sed# ifconfig | sed -n ‘/inet /p‘ | head -1 | awk -F" " ‘{print $2}‘
172.16.126.252
5.20:保存当前处理行的内容
例子:
head –5 /etc/passwd | awk ‘{print “abcdef”}’
#由上知,每处理一行,打印一次字符串abcdef,若想打印当前处理的行呢?
使用0内置变量
head –5 /etc/passwd | awk ‘{print0}’
注意:在awk中调用自定义变量或内置变量是,不需要加双引号,如果加了,会被当成普通字符串输出。只有当要指定输出特定字符串时才需要加””双引号。
5.3 FILENAME:保存当前文件的文件名
awk ‘{print FILENAME}’ /etc/passwd
有多少行输出多少次
如果后面接多个文件呢
awk ‘{print FILENAME}’ a.txt b.txt
处理结果:
a.txt
a.txt
b.txt
b.txt
b.txt
b.txt
b.txt
具体执行过程:
先对第一个文件处理,有多少行输出多少个FILENAME,接下来再处理第2个文件,因有b.txt有5行,所以执行5次print动作,输出5次b.txt.
5.4 NF NR FNR
NF:使用字段分隔符后,每行包含列的个数
NR存储AWK当前处理行的行数
FNR: 存储AWK当前处理行对应文件中的行数
NR和FNR当处理文件是一个时,NF和FNR值相等
例子:
awk -F”:” ‘{print NR}’ /etc/passwd
awk –F”:” ‘{print $0,NR,FNR}’ /etc/passwd
如果后面接多个文件
awk –F”:” ‘{print NR,$FNR}’ a.txt b.txt
会发现如果后面只有一个文件时NR和FNR的值是一样的,当后面接多个文件时NR>FNR,综上,NR>=FNR
6 awk处理数据的顺序(执行顺序)
BEGIN{} 行前处理
{} 行处理
END{} 行后处理
BEGIN{} 行前处理
awk在没有读入行前执行的动作,可以把初始化的操作都写在BEGIN{}容器中。
{} 行处理
awk对读入的每一行数据做处理的动作,把对数据处理的操作都写在{}容器中
END{} 行后处理
awk把所有行都读完之后,执行的处理动作,把处理结果的汇总输出都写在END{}容器中。
例子:
使用awk的输出对应列的数据时,给每一列加标题。(/etc/passwd)
如: username homedir shell
root /root /sbin/bash
bin /bin /sbin/nologin
注意:
在窗口中如果有多个处理动作时要使用;分号
awk ‘{print ENVIRON[“USER”]}’ a.txt
awk ‘{print ENVIRON[“USER”];print $0}’ a.txt
各个容器可以自由组合,也可以重复多次。如可以加多个行处理{}
awk ‘BEGIN{print “username uid gid”}{}’ a.txt
awk ‘BEGIN{print “username uid gid”}{print $1” ”,$3” ”,$4” ”}END{print “FINISH”}’ a.txt
awk ‘{print $0}{print FILENAME}’ a.txt (等价于:awk ‘{print $0;print FILENAME}’ a.txt)
awk ‘BEGIN{}BEGIN{}’ a.txt
awk ‘END{}END{}’ a.txt
小结:
BEGIN{} 一般用于数据的初始化操作
{} 行要执行什么样的操作
END{} 所有行处理完成后
awk ‘BEGIN{print NR}{print NR}END{print NR}’ a.txt
0: BEGIN{print NR}的返回结果
1
2
3
4
5 :END{print NR}的返回结果
行前处理应用:初始化操作
默认分隔符为空格(至少一个)或tab,这个存放在FS这个内置变量中,可以用-F来指定(之前一直这么做),也可以用先前处理对其进行初始化。
如:
awk ‘BEGIN{FS=”:”}{print $1}’ a.txt
#在行处理前将默认分隔符改成:冒号。
注意区别:
awk ‘{print 2}’ a.txt
awk ‘{print 2}’ a.txt
awk ‘{print 1}{print2}’ a.txt
#
7 条件的使用
默认文件有多少行,awk处理多少次,如果只想处理指定范围的行怎么办?
需求:用awk输出偶数行
在处理数据时,在前加上条件,让awk只处理符合条件的行
(不加条件时默认逐行处理,加了条件只有当前行或行里的数据符合条件时,才用处理动作处理。)
格式:
awk 选项 ‘条件{处理动作}’ 文件名
条件格式:(区别与sed)
1.1 数值比较
=
< <=
== !=
如:
awk -F ‘3<500{print1,$3}’ /etc/passwd
#统计当前系统有多少个内建用户、多少个外建用户(awk+wc –l,后面讲了awk的运算符后,可以使用另一种方法)
1.2 字符比较
!=
上面2个运算符后面接字符时要用双引号
1.3 逻辑比较:多个条件时使用
&& 逻辑与
|| 逻辑或
! 逻辑非
如:
awk -F “:” ‘1==”daemon”{print 3,$4}’ /etc/passwd
1.4 /正则表达式/
~ 与正则表达式匹配为真
!~ 与正则表达式不匹配为真
如:
值~/正则表达式/
值!~/正则表达式/
例子:
awk -F ‘1!~/[0-9]/{print1}’ /etc/passwd
8 awk运算符
+
*
/
%
+=
-=
*=
/=
%=
由
awk ‘{print i}’ a.txt
知:
awk中的变量不需要预先定义,可以直接调用。
例子:
[[email protected] awk]# cat a.txt
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
[[email protected] awk]# awd ‘{i=0;i++;print i}‘ a.txt
-bash: awd: command not found
[[email protected] awk]# awk ‘{i=0;i++;print i}‘ a.txt
1
1
1
1
1
[[email protected] awk]# awk ‘{i=0;i++;print i}‘ a.txt #加后,0也就是当前行的内容
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
[[email protected] awk]#
[[email protected] awk]#
[[email protected] awk]# awk ‘BEGIN{i=0}{i++;print i}‘ a.txt
1
2
3
4
5
[[email protected] awk]# awk ‘BEGIN{i=0}{i++}END{print i}‘ a.txt
5
awk ‘FNR%2==0{print FNR,$0}’ /etc/passwd
--------------------------
1-100含7或能被7整除的整数。
seq 100 | awk ‘NR~/7/||NR%7==0{print NR}’
seq 100 | awk ‘$0~/7/||$0%7==0{print $0;i++}END{print i}’
9 awk流程控制
9.1分支结构
9.1.1 单分支
格式1:if(条件判断){条件成立时执行的操作}
#条件用小括号括起来
#条件成立时执行后面的操作,不成立什么也不做
例子:
awk ‘{if(){}}’ /etc/passwd
#注意2个大括号意义区别
具体执行过程:
每行执行’’(单引号)中的动作,当if条件成立时才会执行第二个{}里面的操作。
awk ‘{if(NR==1||NR==10){print $0}}’ /etc/passwd
#2个等号为比较判断,一个等号为赋值
条件成立时,才执行if中的操作,若不成立这一行就不处理了,再进行下一行处理(先判断条件)
格式2:if(条件判断)条件成立时执行的操作 #如果条件成立时,if(){}花括号中只有一个执行动作时,才可以将{}省略,否则,如果条件成立时,要执行多个动作,则{}花括号必须要有。
如:awk ‘{if(NR==1||NR==10)print NR,” ”1 }’ /etc/passwd
#if(NR==1||NR==10)print NR,” ”0这是一个if整体
#print1 是一个整体
#表达的意思也发生了变化,当if条件成立时执行第一个print操作。
#即:每一行执行完if后,还要执行print $1的操作。
9.1.2 双分支
格式1:
if(条件){指令1}else{指令2}
格式2:
if()指令1;else指令2
9.1.3多分支
格式:
if(条件){指令1}else if(条件){指令2}……else if(条件){指令3}else{指令}
10 awk脚本
补充sed中,如何调用shell变量
sed –n ‘namep’ /etc/passwd (x) #会报错,需要用单引号
sed –n ‘’name’p’ /etc/passwd (v) #注意单引号的配对(第一个和第4个,第二个和第三个)
awk中如何调用shell变量
注意:shell变量分为系统级的和用户自定义级别的。
如何调用系统级别的shell变量:
格式:ENVIRON[“shell系统环境变量”]
#这是一个数组类型的内置变量,用来在awk里面调用shell系统环境变量。
#每个数组都是通过下标来引用,而这个内置变量数组是使用shell系统环境的变量名作为数组元素的下标来引用数据。
用户自定义变量如何调用:
格式:-v选项的使用
来引出自定义的awk变量。
例如:awk -v awk_name=$name ‘{print awk_name}’ a.txt
#使用-v关键字来自己定义awk变量,一旦定义awk变量后,就可以在awk的动作处理中直接调用了。
小结:在执行awk时,想要调用shell里面的自定义变量,需要在执行过程中加上-v选项后接awk变量名,并将自定义shell变量的值赋值给awk变量,然后在处理动作中可以直接调用之前定义的awk变量(相当于间接调用shell中的自定义变量)。
以上是关于awk的主要内容,如果未能解决你的问题,请参考以下文章