疯狂的awk

awk和sed是文本编辑的两大神器,都有相应的书籍介绍,向我等屌丝就不用那么深入了,就将些常用浅显的用法记录(不定期更新)下来供日后查询。
1、语法构成 awk由3部分构成:BEGIN语句块、END语句块和能够使用模式匹配的通用语句块,每个部分为都是可选的。

1
2
3
#单引号或双引号均可,不过有区别下面有举例介绍 
awk 'BEGIN {statements} {statements} END {statements}'
awk "BEGIN {statements} {statements} END {statements}"

2、执行流程

  1. 执行BEGIN {statements} 语句块中的语句;
  2. 从文件或stdin中读取一行,然后执行pattern {commands}。重复这个过程,直到文件全部被读取完毕;
  3. 当读至输入流input stream末尾时,执行END {commands}语句块。
    awk中还有些特殊的变量需要注意下
    NR:执行过程中,当前的行号
    NF:执行过程中,当前行的当前字段数
    $0:执行过程中,当前行的文本内容
    $1:执行过程中,当前行第一个字段的文本内容
    $2:执行过程中,当前行第二个字段的文本内容

3、用法记录
打印文件指定行区间的内容,如:打印第1行到第2行的内容

1
2
3
4
5
6
7
8
$ awk "{if(NR>=1){if(NR<=2)print}}" install.log 
Installing libgcc-4.4.7-3.el6.x86_64
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY

#也可以着这样
$ awk "{if(NR>=1&&NR<=2)print}" install.log
Installing libgcc-4.4.7-3.el6.x86_64
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY

统计文件总行数

1
2
$ awk "END {print NR}" install.log 
836

打印文件指定行区间的内容,使用-v参数将外部变量值传递给awk为每行添加特定的字符串

1
2
3
4
$ awk -v h=' 自定义字符串' '{if(NR>=2&&NR<=4) print $0 h}' install.log 
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY 自定义字符串
Installing xml-common-0.6.3-32.el6.noarch 自定义字符串
Installing ca-certificates-2010.63-3.el6_1.5.noarch 自定义字符串

传递多个外部变量值给awk,例如传递变量var1、var2、var3的值给awk。

1
2
3
4
5
6
7
8
9
10
11
12
$ var1="string01";var2="string02";var3="string03" 
# 标准输入时这样传递
$ cat install.log | awk '{if(NR>=2&&NR<=4) print v1,$1,v2,$2,v3}' v1=$var1 v2=$var2 v3=$var3
string01 warning: string02 libgcc-4.4.7-3.el6.x86_64: string03
string01 Installing string02 xml-common-0.6.3-32.el6.noarch string03
string01 Installing string02 ca-certificates-2010.63-3.el6_1.5.noarch string03

#非标准输入可以这样传递
$ awk '{if(NR>=2&&NR<=4) print v1,$1,v2,$2,v3}' v1=$var1 v2=$var2 v3=$var3 install.log
string01 warning: string02 libgcc-4.4.7-3.el6.x86_64: string03
string01 Installing string02 xml-common-0.6.3-32.el6.noarch string03
string01 Installing string02 ca-certificates-2010.63-3.el6_1.5.noarch string03

计算1到100的和,就是C语言嘛。

1
2
$ awk 'BEGIN { for(i=1; i<=100; i++) sum+=i; print sum;}' 
5050

双引号" "和单引号' '的区别,如果使用的是双引号一些特许的变量需要用转义符号\转义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 打印文本的1-2行内容
$ awk "{if(NR>=1&&NR<=2)print}" install.log
Installing libgcc-4.4.7-3.el6.x86_64
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY

# 打印文本的1-2行内容的第二个字段内容,因为用的是双引号所有$2这个awk的特许变量没有被awk真确解析
$ awk "{if(NR>=1&&NR<=2)print $2}" install.log
Installing libgcc-4.4.7-3.el6.x86_64
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY

# 使用转义符号"\"或者单引号都可以真确的打印文本的1-2行内容的第二个字段内容
$ awk "{if(NR>=1&&NR<=2)print \$2}" install.log
libgcc-4.4.7-3.el6.x86_64
libgcc-4.4.7-3.el6.x86_64:
$ awk '{if(NR>=1&&NR<=2)print $2}' install.log
libgcc-4.4.7-3.el6.x86_64
libgcc-4.4.7-3.el6.x86_64:

打印文本的字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 打印第二行
$ awk '{if(NR==2)print}' install.log
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
# 打印第二行第1个自段
$ awk '{if(NR==2)print $1}' install.log
warning:
# 打印第二行第2个字段
$ awk '{if(NR==2)print $2}' install.log
libgcc-4.4.7-3.el6.x86_64:
# 打印第二行的倒数第1个字段
$ awk '{if(NR==2)print $NF}' install.log
NOKEY
# 打印第二行的倒数第2个字段
$ awk '{if(NR==2)print $(NF-1)}' install.log
c105b9de:
# 打印整个文本的第一个字段
$ awk '{print $1}' install.log
Installing
warning:
Installing
Installing
... ... ...

自定义字段界定符,系统默认的界定符是空白字符,使用awk时可以使用-F参数自定义界定符

1
2
3
4
5
6
7
8
9
10
11
12
# 打印第二行内容
$ awk '{if(NR==2) print}' install.log
warning: libgcc-4.4.7-3.el6.x86_64: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
# 使用默认的界定符打印第二行的第二个字段
$ awk '{if(NR==2) print $2}' install.log
libgcc-4.4.7-3.el6.x86_64:
# 使用自定义的界定符'.'打印第二行的第二个字段
$ awk -F'.' '{if(NR==2) print $2}' install.log
4
# 使用自定义的界定符'/'打印第二行的第二个字段
$ awk -F'/' '{if(NR==2) print $2}' install.log
SHA1 Signature, key ID c105b9de: NOKEY

目前就整这些,以后接触到新的用法时再更新。

----------------本文结束 感谢阅读----------------