一、awk 模式和动作
awk程序组成: pattern { action statements }
1.1 awk pattern(模式)
- BEGIN
- END
-
/regular expression/
正则表达式。需要用//包含起来 -
relational expression
关系表达式。一般用于测试某些字段是否匹配某些正则表达式或某个记录是否满足特定条件。如:
awk 'NR !=1 {print $0}' testfile。在这里我想强调的一个,这里的关系表达式和if语句是不一样的。if语句是要写在{action} 中的。两个例子
echo "$(df -h)" | awk '{ if (NR != 1 ) print $0}' # 正确
echo "$(df -h)" | awk '(NR != 1 ) {print $0}' #正确
echo "$(df -h)" | awk 'if (NR != 1 ) {print $0}' #错误
-
pattern && pattern
模式之间可以进行与操作
echo "$(df -h)" | awk ' (NR != 1 && NR <= 2) { print $0}'
-
pattern || pattern
模式之间可以进行或操作 - pattern ? pattern : pattern
- (pattern)
-
! pattern
非。模式的非操作 -
pattern1, pattern2
指定一个行的范围。该语法不能包括BEGIN和END模式。
二、awk 运算符
运算符 | 含义 |
---|---|
(...) | 组 |
$ | 字段引用 |
++ -- | 自增/自减 |
+ - ! | 一元加,减和逻辑非 |
* / % | 乘法 除法 模 |
+ - | 加,减 |
space | String concatenation. |
< > <= >= != == | 关系运算符 |
~ !~ | 匹配正则表达式和不匹配正则表达式 |
in | 数组成员检测 |
&& | 逻辑与 |
?: | C条件表达式 |
还有逻辑或 ||(markdown语法转义有问题,所以泻在这列。。。); ** | |& **—— Piped I/O for getline, print, and printf.
三、awk内置变量
变量 | 含义 |
---|---|
$0 | 完整的输入记录。 |
ARGC | 命令行参数的数目。 |
ARGIND | 命令行中当前文件的位置(从0开始算)。 |
ARGV | 包含命令行参数的数组。 |
BINMODE | |
CONVFMT | 数字转换格式(默认值为%.6g) |
ENVIRON | 环境变量关联数组。 |
ERRNO | 最后一个系统错误的描述。 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔)。 |
FILENAME | 当前文件名。 |
FNR | 同NR,但相对于当前文件。 |
FS | 字段分隔符(默认是任何空格)。 |
IGNORECASE | 如果为真,则进行忽略大小写的匹配。 |
LINT | |
NF | 当前记录中的字段数。 |
NR | 当前记录数(即当前行,每处理完一条记录,NR值+1) |
OFMT | 数字的输出格式(默认值是%.6g)。 |
OFS | 输出字段分隔符(默认值是一个空格)。 |
ORS | 输出记录分隔符(默认值是一个换行符)。 |
PROCINFO | |
RLENGTH | 由match函数所匹配的字符串的长度。 |
RS | 记录分隔符(默认是一个换行符)。 |
RT | |
RSTART | 由match函数所匹配的字符串的第一个位置。 |
RLENGTH | |
SUBSEP | 数组下标分隔符(默认值是\034)。 |
TEXTDOMAIN |
四、控住语句
4.1 条件控制语句
if (condition) statement [ else statement ]
4.2 while
while (condition) statement
do statement while (condition)
4.3 for语句
for (expr1; expr2; expr3) statement
for (var in array) statement
4.4 break、continue、delete
4.5 exit [ expression ]
4.6 { statements }
五、内建函数
函数 | 功能 |
---|---|
system() | 系统命令调用。eg: eawk '{system("date")}' |
length() | 计算字符长度。 eg: awk '{if(NR==1){len=length($NF); print $NF"="len}}' /var/log/cron |
sub() | 1. sub (regular expression, substitution string):如果匹配正则表达式,则用substitution string替换匹配的字符串(没有target string时,则直接匹配$0中的字符串,我一般都是操作某个字段的)。2. sub (regular expression, substitution string, target string):对于target字符串,如果匹配正则表达式,则用substitution string替换到匹配的字符串,并返回替换数 |
注意,sub返回的是第一次匹配
# 没有target的情况下匹配IP。
[yantao@yantao ~]$ ifconfig | awk '/inet/ {sub(/addr:/,"");ip=$2;print ip}'
10.1.1.46
42.51.169.10
111.7.132.211
127.0.0.1
#
[yantao@yantao ~]$ ifconfig | awk '/inet/ {sub(/addr:/,"",$2);print}'
inet 10.1.1.46 Bcast:10.1.1.255 Mask:255.255.255.0
inet 42.51.169.10 Bcast:42.51.169.255 Mask:255.255.255.0
inet 111.7.132.211 Bcast:111.7.132.223 Mask:255.255.255.224
inet 127.0.0.1 Mask:255.0.0.0
最后、示例
- df -h结果清洗(特殊的挂载点不要)
[root@logan ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 9.7G 5.5G 3.7G 61% /
tmpfs 491M 4.0K 491M 1% /dev/shm
/dev/sda3 18G 8.8G 8.4G 52% /usr/local
/usr/local/src/iso/CentOS-6.8-x86_64-bin-DVD1.iso 3.7G 3.7G 0 100% /iso/CentOS-6.8
[root@logan ~]# echo "$(df -h)" | awk '(NR != 1 && $6 != "/dev/shm") && /[/a-z]+$/ {print $6}'
/
/usr/local
这里用到了模式之间的与以及(parrten)模式
- if语句使用
还是以df -h结果清洗为例
[root@logan ~]# echo "$(df -h)" | awk '/[a-z/]+$/ { if(NR != 1 && $6 != "/dev/shm"){print $6}}'
/
/usr/local
- 检测磁盘只读
df -h | awk 'NR != 1 && ($6 != "/dev/shm" ) { system("touch "$6) }' touch: setting times of `/data3': Read-only file system
touch: setting times of `/data5': Read-only file system
。。。。。awk持续更新这篇文章持续更新。会增加更多的示例。错误之处请指正
网友评论