awk 基础命令
大家好哈,前面总结了2篇 sed 流编辑器的文章,现在我们来看看另外一个强大的文本编辑工具 awk。
sed 和 awk 系列文章:
sed 基础命令:http://www.huangdc.com/109
sed 高级命令:http://www.huangdc.com/123
awk 基础命令 : http://www.huangdc.com/143
awk 高级命令:http://www.huangdc.com/146
运维工作中,对于创建和修改文本文件的同学来说,sed和awk是编辑的动力工具,这些工作中所做的大部分事情都可以用文本编辑器交互式的完成。然而,使用sed 和 awk在达到同样结果的情况下可以节省大量重复性工作 sed和awk 是特殊的,它们需要花时间来学习,但是它们的功能将带给你事半功倍的效果,尤其是当文本编辑是你运维职业的正常组成部分时,啰里啰嗦一大堆,哈哈
awk : AWK是贝尔实验室1977年搞出来的文本出现神器,之所以叫AWK是因为其取了三 位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的 首字符。
AWK 是一门专门用于文本处理的编程语言,它的目的仅有文本处理AWK具有编程语言的特性,有内置函数,有逻辑语句,有输入输出语句,其实它看起来很像C语言, 只不过所有功能集中于文本处理
awk 与 sed 比较:
sed:可以在一个地方指定所有的编辑指令,然后通过文件传递一次来执行他们,但是它在每次处理多于一行的能力方面有限制
awk:与Sed不同,AWK最强大的功能在于处理结构化的文本,也就是说文本有一定 的组织结构的.
awk命令行的语法
可以大致相同的方式调用sed和awk,命令行语法是:
command [options] script filename
几乎和所有的unix程序一样,sed和awk都可以从标准输入中取得输入并将输出发送到标准输出。如果指定文件名filename,输入就取自那个文件。输出包含处理后的信息
[DcHuang@vm200-78 ~]$ cat test.txt
11 22 33 44
55 66 77 88
[DcHuang@vm200-78 ~]$ sed 's/66/huangdc.com/g' test.txt
11 22 33 44
55 huangdc.com 77 88
[DcHuang@vm200-78 ~]$ awk '{gsub("66","huangdc.com");print}' test.txt
11 22 33 44
55 huangdc.com 77 88
与sed相似,awk为每个输入行执行一套指令。可以在命令行上指令或者创建脚本文件
1、指定简单命令
可以在命令行上指定简单的编辑命令
awk ‘instruction’ file
每次从一个或者多个文件中读入一行或者从标准输入中读入一行。指令必须包含在单引号中,从而与shell区分开(指令几乎总是包含大括号和/或者美元符号,shell将它们解释为特殊符号)
2、脚本文件
awk程序通常被放置在可以对它们进行测试和修改的文件中。用脚本文件调用awk的语法如下:
awk -f scriptfile file -f
选项的工作方式与在sed中相同
awk程序设计模型
可以把awk脚本看做由3部分组成:
a、处理输入前做处理
b、处理输入过程中将做的处理(指令被写成一系列的模式/动作过程)
c、处理输入完成后做的处理
awk [option] ‘BEGIN{}//{}ENG{}’ file
第一部分:BEGIN{ 这里面放的是执行前的语句 }
中间部分:{ 这里面放的是处理每一行时要执行的语句 }
第三部分:END{ 这里面放的是处理完所有的行后要执行的语句 }
注意:主要的事情是每个模式/动作过程位于主输入循环中,且负责读取输 入行所编写的过程将应用于每个输入行,而且一次一行
awk模式匹配
当awk读入一行时,它试图匹配脚本中的每个模式匹配规则。只有与一个 特定的模式相匹配的输入行才能成为操作对象。如果没有指定操作,于 模式相匹配的输入行将被打印出来(执行打印语句i一个默认操作)
/匹配正则/{动作}
## 实例文本文件test.txt 内容
[DcHuang@vm200-78 ~]$ cat test.txt
11111111
abcdefgh
abcdefgh
44444444
## 匹配abc ,默认会输出匹配行 (默认有 print 动作)
[DcHuang@vm200-78 ~]$ awk '/abc/' test.txt
abcdefgh
abcdefgh
[DcHuang@vm200-78 ~]$ awk '/abc/{print }' test.txt
abcdefgh
abcdefgh
## 匹配abc ,指定输出内容huangdc.com ; 匹配2行,所以输出2行 huangdc.com
[DcHuang@vm200-78 ~]$ awk '/abc/{print "huangdc.com"}' test.txt
huangdc.com
huangdc.com
[DcHuang@vm200-78 ~]$
awk系统变量
awk中有许多系统变量或内置变量。awk有两种类型的系统变量:
第一种类型定义的变量默认值可以改变。(如默认的字段和记录分割符)
第二种类型定义的变量值可以用于报告或数据处理中。(如当前记录中字 段的数量)
变量 | 作用 |
---|---|
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1~$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或Tab |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
RS | 输入的记录分隔符, 默认为换行符 |
OFS | 输出字段分隔符, 默认也是空格 |
ORS | 输出的记录分隔符,默认为换行符 |
FILENAME | 当前输入文件的名字 |
awk记录和字段
awk假设它的输入是有结构的,而不只是一串无规则的字符。在最简单的情 况下,它将每个输入行作为一条记录,而将由空格或制表符分隔的单词作为 字段(用来分隔字段的字符被称为分隔符)
awk用字段操作符($)来指定字段,在改操作后面跟着一个数字或者变量,用 来标识字段的位置,“ $1”表示第一个字段,“ $2”表示第一个字段,- F’**’ 指定字段分割符
## 实例文本文件 test.txt
[DcHuang@vm200-78 ~]$ cat test.txt
11111111,AAA,huangdc A
abcdefgh,BBB,irank B
abcdefgh,CCC,comcom C
44444444,DDD,555555 D
## 打印第二字段 ,不指定分割符,默认分隔符为“空格”
[DcHuang@vm200-78 ~]$ awk '{print $2}' test.txt
A
B
C
D
## 打印第二字段 ,指定分割符为逗号","
[DcHuang@vm200-78 ~]$ awk -F',' '{print $2}' test.txt
AAA
BBB
CCC
DDD
## 匹配huang的行并打印第二字段 ,指定分割符为逗号","
[DcHuang@vm200-78 ~]$ awk -F',' '/huang/{print $2}' test.txt
AAA
## 匹配huang的行并打印第二字段 ,在BEGIN{}指定分割符为逗号","
[DcHuang@vm200-78 ~]$ awk 'BEGIN{FS=","}/huang/{print $2}' test.txt
AAA
## 匹配huang的行并打印第二字段 ,在BEGIN{}指定分割符为空格" "
[DcHuang@vm200-78 ~]$ awk 'BEGIN{FS=" "}/huang/{print $2}' test.txt
A
awk表达式
可以使用表达式来存储、操作和检索数据。一个表达式通过计算返回一个 值,表达式由数字和字符串常量、变量、操作符、函数和正则表达式组成
算术操作符: +(加)、-(减) 、*(乘)、 /(除)、%(取摸)、^(取幂)
赋值操作符: ++(变量加1)、–(变量减1)、+=(将加的结果赋给变量)、-=、*=、/=、 %=、^=
## 实例文本文件 test.txt
[DcHuang@vm200-78 ~]$ cat test.txt
11111111,AAA,huangdc A
abcdefgh,BBB,irank B
abcdefgh,CCC,comcom C
44444444,DDD,555555 D
[DcHuang@vm200-78 ~]$
## 计算文本文件 test.txt 的空行
[DcHuang@vm200-78 ~]$ awk '/^$/{print x+=1}' test.txt
1
2
3
4
## 计算文本文件 test.txt 的空行,END{} 输出最好结果
[DcHuang@vm200-78 ~]$ awk '/^$/{x+=1}END{print x}' test.txt
4
awk关系、布尔操作符
关系操作符和布尔操作符用于在两个表达式直接进行比较
关系操作符: <、>、<=、>=、==、!=、~、!- (小于、大于、小于或等于、大于或等于、相等、不相等、匹配、不匹配)
布尔操作符: | 、&&、! (逻辑或、逻辑与、逻辑非) |
## 实例文本文件 test.txt
[DcHuang@vm200-78 ~]$ cat test.txt
1,11111111,AAA,huangdc A
3,abcdefgh,BBB,irank B
30,abcdefgh,CCC,comcom C
50,44444444,DDD,555555 D
## 打印第一字段 大于10 的行
[DcHuang@vm200-78 ~]$ awk -F',' '$1>10{print }' test.txt
30,abcdefgh,CCC,comcom C
50,44444444,DDD,555555 D
## 打印第一字段 大于10 且 小于40 的行
[DcHuang@vm200-78 ~]$ awk -F',' '$1>10 && $1<40{print }' test.txt
30,abcdefgh,CCC,comcom C
awk格式打印
awk提供的printf 可以替代print 语句,printf是借用c程序设计语言。
完成的语法由两部分组成:
printf(for mat-expression [,arguments])
实例输出 10/3 的结果
## 输出整数
[DcHuang@vm200-78 ~]$ echo '10' | awk '{printf("%d\n",$1/3)}'
3
## 输出浮点数
[DcHuang@vm200-78 ~]$ echo '10' | awk '{printf("%f\n",$1/3)}'
3.333333
## 输出浮点数,保留2位小数
[DcHuang@vm200-78 ~]$ echo '10' | awk '{printf("%.2f\n",$1/3)}'
3.33
awk向脚本传递参数
在awk中,一个容易引起混乱的地方就是向脚本传递参数。参数将值赋给一个变量,这个变量可以在awk脚本中访问。这个变量可以在命令行上设置,放在脚本的后面,文件的前面
awk ‘script’ var=value inputfile
注意:命令行参数的一个重要限制是它们在BEGIN过程中是不可用的
## 向awk 传2个参数 G 和 H
[DcHuang@vm200-78 ~]$ echo '10' | awk '{print $1 * G * H }' G=5 H=4
200
## 向awk 的BEGIN 部分传2个参数 G 和 H ,无效
[DcHuang@vm200-78 ~]$ echo '10' | awk 'BEGIN{print $1 * G * H }' G=5 H=4
0
## 向awk 的END 部分传2个参数 G 和 H ,有效
[DcHuang@vm200-78 ~]$ echo '10' | awk 'END{print $1 * G * H }' G=5 H=4
200
[DcHuang@vm200-78 ~]$
好了,先写那么多
awk 程序设计模型 , 模式匹配 , 系统变量 , 记录和字段 , 表达式 , 关系操作符和布尔操作符 ,格式打印,向脚本传递参数