目录
一、awk
awk是一种文本和数据进行处理的编程语言。用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息。
二、语法
awk [POSIX or GNU style options] -f progfile [--] file ...
awk [POSIX or GNU style options] [--] 'program' file ...
三、选项和参数
1.选项
1)常用选项
- -F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:,默认的分隔符是连续的空格或制表符
- -v var=value 赋值一个用户定义变量,将外部变量传递给awk #var=variable,变量
- -f scripfile 从脚本文件中读取awk命令
2)完整选项
POSIX options: GNU long options: (standard)
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
Short options: GNU long options: (extensions)
-b --characters-as-bytes
-c --traditional
-C --copyright
-d[file] --dump-variables[=file]
-e 'program-text' --source='program-text'
-E file --exec=file
-g --gen-pot
-h --help
-L [fatal] --lint[=fatal]
-n --non-decimal-data
-N --use-lc-numeric
-O --optimize
-p[file] --profile[=file]
-P --posix
-r --re-interval
-S --sandbox
-t --lint-old
-V --version
2.参数
1)常用参数(内置变量)
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
FS(输入字段分隔符) # 以什么符号去分割,处理列的分隔,划分字段
OFS(输出字段分隔符) # 以什么分隔符显示
NR(Number of record)行数
FNR按不同的文件分开
RS(输入记录分隔符) awk 'BEGIN{RS=" "}{print$0}' sararies.txt #处理行的分隔,划分行
ORS(输出记录分隔符)
NF 字段个数
2)完整参数(内置变量)
**$n** 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
**$0** 这个变量包含执行过程中当前行的文本内容。
[N] **ARGC** 命令行参数的数目。
[G] **ARGIND** 命令行中当前文件的位置(从0开始算)。
[N] **ARGV** 包含命令行参数的数组。
[G] **CONVFMT** 数字转换格式(默认值为%.6g)。
[P] **ENVIRON** 环境变量关联数组。
[N] **ERRNO** 最后一个系统错误的描述。
[G] **FIELDWIDTHS** 字段宽度列表(用空格键分隔)。
[A] **FILENAME** 当前输入文件的名。
[P] **FNR** 同NR,但相对于当前文件。
[A] **FS** 字段分隔符(默认是任何空格)。
[G] **IGNORECASE** 如果为真,则进行忽略大小写的匹配。
[A] **NF** 表示字段数,在执行过程中对应于当前的字段数。
[A] **NR** 表示记录数,在执行过程中对应于当前的行号。
[A] **OFMT** 数字的输出格式(默认值是%.6g)。
[A] **OFS** 输出字段分隔符(默认值是一个空格)。
[A] **ORS** 输出记录分隔符(默认值是一个换行符)。
[A] **RS** 记录分隔符(默认是一个换行符)。
[N] **RSTART** 由match函数所匹配的字符串的第一个位置。
[N] **RLENGTH** 由match函数所匹配的字符串的长度。
[N] **SUBSEP** 数组下标分隔符(默认值是34)。
3)拓展:转义序列
\\ \自身
\$ 转义$
\t 制表符
\b 退格符
\r 回车符
\n 换行符
\c 取消换行
四、模式和操作
awk脚本是由模式和操作组成的。
1.模式
模式可以是以下任意一个:
- /正则表达式/:使用通配符的扩展集。
- 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。
- 模式匹配表达式:用运算符
~
(匹配)和!~
(不匹配)。 - BEGIN语句块、pattern语句块、END语句块:参见awk的工作原理
2.操作
操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,主要部分是:
- 变量或数组赋值
- 输出命令
- 内置函数
- 控制流语句
五、awk脚本的基本结构
awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file
一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,通常在单引号中。例如:
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk 参数 'BEGIN{处理之前要做的} {处理内容} END{处理之后的内容}'
BEGIN{}
行处理前
{}
处理内容
END{}
行处理 行处理后
- BEGIN{}在处理文本之前做的事情,只执行一次
- {}在处理文本时做的事情,有多少次执行多少次
- END{}在处理文之后做的事情,只执行一次
六、awk的工作原理
- awk使用一行作为输入,并将这一行赋给变量$0,每一行可称作为一个记录,以换行符结束
- 然后,行被:分解成字段,每个字段存储在已编号的变量中,从$1开始
- awk如何知道空格来分隔字段的呢?因为有一个内部变量FS来确定字段分隔符,初始时,FS赋为空格或者是tab
- awk打印字段时,将以设置的方法,使用print函数打印,awk在打印的字段间加上空格,因为$1,$3间有一个,逗号。逗号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格
- awk打印字段时,将从文件中获取每一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程持续到处理文件结束
七、使用
1.模块的使用
[root@slave ~]# awk 'BEGIN{print 1/2} {print "ok"} END{print "----"}' /etc/hosts 0.5 ok ok ok ok ok ----
2。$0
awk使用一行作为输入,并将这一行赋给变量$0
awk 'BEGIN{i=1}{print i++}' /etc/passwd #每一行只有行号
awk 'BEGIN{i=1}{print i++,$0}' /etc/passwd #每一行行号后面跟,以空格分开的每一行文件内容
3.$n
$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段
[root@master srv]# cat case aa bb cc dd ee ff gg hh ii 11 22 33 44 55 66
[root@master srv]# awk '{print $1,$2}' case aa bb dd ee gg hh 11 22 44 55
4.FS
FS(输入字段分隔符) # 以什么符号去分割,处理列的分隔,划分字段
[root@master srv]# cat case aa:bb:cc dd:ee:ff gg:hh:ii 11:22:33 44:55:66
1) -F
[root@master srv]# awk -F: '{print $3}' case cc ff ii 33 66
2) FS="*"
[root@master srv]# awk 'BEGIN{FS=":"} {print $1}' case aa dd gg 11 44
#设置特殊变量需在“BEGIN”模块中
5.OFS
OFS(输出字段分隔符) # 以什么分隔符显示
#逗号比较特殊,映射为另一个变量,成为输出字段分隔符OFS,OFS默认为空格
[root@master srv]# awk 'BEGIN{FS=":";OFS="-"} {print $1,$2}' case aa-bb dd-ee gg-hh 11-22 44-55
6. RS
RS(输入记录分隔符) #处理行的分隔,划分行
[root@master srv]# cat case aaobbocc
[root@master srv]# awk 'BEGIN{RS="o"} {print $1}' case aa bb cc
7.ORS
ORS(输出记录分隔符)
#将默认作为分隔行字符的换行符变为空格
[root@master srv]# awk 'BEGIN{RS="o";ORS=" "} {print $0}' case aa bb cc
8.NR(Number of record)
NR 表示记录数,在执行过程中对应于当前的行号
#表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
[root@master srv]# cat -b case #-b, --number-nonblank 对非空输出行编号 1 aa bb cc 2 dd ee ff 3 gg hh ii 4 11 22 33 5 44 55 66
#打印行号
[root@master srv]# awk '{print NR}' case 1 2 3 4 5
#每行打印字段为行号数的字段
[root@master srv]# awk '{print $NR}' case aa ee ii
#$(NR-1)
[root@master srv]# awk '{print $(NR-1)}' case aa bb cc #$0记录本身 dd hh 33
#NR==
[root@master srv]# awk 'NR==2{print $1}' case dd
9.FNR
FNR 不同文件分开的行号
[root@master srv]# awk '{print FNR,$1}' case test.txt 1 aa 2 dd 3 gg 4 11 5 44 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
10.NF
NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
[root@master srv]# awk '{print NF,$0}' case 3 aa bb cc 3 dd ee ff 3 gg hh ii 3 11 22 33 3 44 55 66