awk作用:能提供一个类编程环境来修改和重新组织文件中的数据。
1. awk命令格式
awk程序的基本格式如下:awk options program file
基本的命令语法:awk option 'pattern {action}' file
其中pattern表示AWK在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。花括号用于根据特定的模式对一系列指令进行分组。
awk选项
-F fs | 指定行中划分数据字段的字段分隔符 |
-f file | 从指定的文件中读取程序 |
-v var=value | 定义awk程序中的一个变量及其默认值 |
-mf N | 指定要处理的数据文件中的最大字段数 |
-mr N | 指定数据文件中的最大数据行数 |
-W keyword | 指定awk的兼容模式或警告等级 |
模式
Pattern | Description |
BEGIN{ } | 给程序赋予初始状态,先执行的工作 |
END{ } | 程序结束之后执行的一些扫尾工作 |
/regular expression/ | 为每个输入记录匹配正则表达式 |
pattern && pattern | 逻辑and,满足两个模式 |
pattern || pattern | 逻辑or,满足其中一个模式 |
! pattern | 逻辑not, 不满足模式 |
pattern1, pattern2 | 范围模式,匹配所有模式1的记录,直到匹配到模式2 |
2. 从命令行读取程序脚本
有三种方式调用awk,
第一种是命令行方式,如:
awk [-F 分隔符] '命令(command)' input-files
比如
$ gawk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
[...]
第二种方法是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。
第三种方式是将所有的awk命令插入一个单独文件,然后调用:
awk -f awkscriptfile inputfile
- f选项指明在文件awkscript中的awk脚本,inputfile( s )是使用awk进行浏览的文件名。
$ cat script2.awk
{print $1 "'s home directory is " $6}
$
$awk -F: -f script2.awk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
[...]
Christine's home directory is /home/Christine
Samantha's home directory is /home/Samantha
Timothy's home directory is /home/Timothy
3. 使用数据字段变量
awk会将如下变量分配给它在文本行中发现的数据字段:
$0代表整个文本行;
$1代表文本行中的第1个数据字段;
$2代表文本行中的第2个数据字段;
$n代表文本行中的第n个数据字段。
在文本行中,每个数据字段都是通过字段分隔符划分的。awk在读取一行文本时,会用预定义的字段分隔符划分每个数据字段。awk中默认的字段分隔符是任意的空白字符(例如空格或制表符)。
只显示第1个数据字段的值。
$ cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.
$
$ gawk '{print $1}' data2.txt
One
Two
Three
$
读取采用了其他字段分隔符的文件,可以用-F选项指定。由于/etc/passwd文件用冒号来分隔数字字段,因而如果要划分开每个数据元素,则必须在awk选项中将冒号指定为字段分隔符。
$ gawk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
4.在程序脚本中使用多个命令
要在命令行上的程序脚本中使用多条命令,只要在命令之间放个分号即可。
$ echo "My name is Rich" | gawk '{$4="Christine"; print $0}'
My name is Christine
$
5. 从文件中读取程序
awk编辑器允许将程序存储到文件中,然后再在命令行中引用。
$ cat script2.awk
{print $1 "'s home directory is " $6}
$
$ gawk -F: -f script2.awk /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
[...]
Christine's home directory is /home/Christine
Samantha's home directory is /home/Samantha
Timothy's home directory is /home/Timothy
$
指定多个分隔符,作为同一个分隔符处理:
# tail -n3 /etc/services |awk -F'[/#]' '{print $3}'
iqobject
iqobject
Matahari
Broker
# tail -n3 /etc/services |awk -F'[/#]' '{print $1}'
iqobject 48619
iqobject 48619
matahari 49000
# tail -n3 /etc/services |awk -F'[ /]+' '{print $2}'
48619
48619
49000
[]元字符的意思是符号其中任意一个字符,也就是说每遇到一个/或#时就分隔一个字段,当用多个分隔符时,就能更方面处理字段了。
6. 在处理数据前运行脚本
使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行。
BEGIN模式是在处理文件之前执行该操作,常用于修改内置变量、变量赋值和打印输出的页眉或标题。
$ awk 'BEGIN {print "Hello World!"}'
Hello World!
$
$ cat data3.txt
Line 1
Line 2
Line 3
$
$ gawk 'BEGIN {print "The data3 File Contents:"} {print $0}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
$
7. 在处理数据后运行脚本
END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。
$ gawk 'BEGIN {print "The data3 File Contents:"} {print $0} END {print "End of File"}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
End of File
8./re/正则匹配 匹配包含tcp的行:
# tail /etc/services |awk '/tcp/{print $0}'
匹配开头是blp5的行:
# tail /etc/services |awk '/^blp5/{print $0}'
9.逻辑and、or和not 匹配
记录中包含blp5和tcp的行: # tail /etc/services |awk '/blp5/ && /tcp/{print $0}'
匹配记录中包含blp5或tcp的行: # tail /etc/services |awk '/blp5/ || /tcp/{print $0}'
不匹配开头是#和空行: # awk '! /^#/ && ! /^$/{print $0}' /etc/httpd/conf/httpd.conf
10.匹配范围 # tail /etc/services |awk '/^blp5/,/^com/'
11.变量赋值
# awk -v a=123 'BEGIN{print a}'
123
系统变量作为awk变量的值:
# a=123
# awk -v a=$a 'BEGIN{print a}'
123
或使用单引号
# awk 'BEGIN{print '$a'}'
123