AWK入门指南html
# 使用yum安装
yum install gawk
# 安装后检查是否安装ok
which awk
## 通常输出安装路径是在: /bin/awk
复制代码
假设存在一个文件 emp.data,其中包含员工的姓名、薪资(美圆/小时)以及小时数,一个员工一行数据,其内容以下:node
Beth 4.00 0
Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
复制代码
若是想打印出 工做时长超过0小时的员工姓名和工资(薪资乘以时间),如下命令能够完成:linux
awk '$3>0 {print $1, $2*$3}' emp.data
复制代码
获得以下输出:正则表达式
kathy 40
Mark 100
Mary 121
Susie 76.5
复制代码
该命令告诉系统执行括号内的awk程序,从输入文件 emp.data 获取所须要的数据。引号内的部分是个完整的awk程序,包含单个 模式-动做 语句。模式 $3>0 用于匹配第三列大于0的输入行,动做: {print $1, $2*$3}
打印每一个匹配行的第一个字段、第二个字段与第三个字段的乘积。redis
还能够打印没有工做过的员工姓名:shell
awk '$3==0 {print $1}' emp.data
复制代码
将会输出:编程
Beth
Dan
复制代码
回过头来看一下上述命令。引号之间的部分是awk编程语言写就的程序。 每一个awk程序都是 一个或多个 模式-动做 语句的序列:数组
pattern {pattern} pattern {pattern} ...bash
awk 的基本操做是一行一行的扫描输入,搜索匹配任意程序中模式的行。 词语“匹配”的准确意义是视具体的模式而言,对于模式 $3>0 来讲,意思是“条件为真”。 每一个模式依次测试每一个输入行。对于匹配到行的模式,其对应的动做(也许包含多步)获得执行,而后读取下一行并继续匹配,直到全部的输入读取完毕。服务器
模式 | 动做 |
---|---|
$3==0 | {print $1} |
模式-动做 语句中的 模式或动做(但不是二者同时省略)均可以省略。若是某个模式没有动做,例如:
$3==0
那么模式匹配到的每一行都会被打出来。输出以下:
Beth 4.00 0
Dan 3.75 0
复制代码
若是是没有动做的模式,例如: {print $1}
则会打印第一列,输出以下:
Beth
Dan
kathy
Mark
Mary
Susie
复制代码
因为模式和动做二者任一都是可选的,因此须要使用大括号包围动做用以区分其余模式。
执行awk程序有多种,能够输入以下形式的命令行: awk 'program codes' inputfiles
从而在每一个指定的输入文件上执行这个program。例如: awk '$3==0 {print $1}' file1 file2
打印 file1 和 file2 文件中第三列为0的每一行的第一个字段。
也能够省略命令行中的输入文件,仅仅输入: awk 'program codes'
在这种状况下,awk 将会应用于你在终端接着输入的任意数据行,直到你输入一个文件结束信号(Unix系统上为control-d)。示例:
awk '$3>0 {print $1}'
Mary 20 1000 #输入该行回车
Mary # 计算机输出,匹配到了信息
Belly 30 3000 #继续输入改行
Belly #计算机输出
复制代码
注意事项: 命令行中的程序是用单引号包围着的。这会防止shell解释程序中$这样的字符,也容许程序的长度超过一行。 当程序比较长的时候,能够将程序写入到一个文件,如下命令行: awk -f programfile optional list of input files
其中 -f 选项指示 awk 从指定文件中获取程序。可使用任意文件名替换 programfile。
若是你的 awk 程序存在错误, awk 会给你一些诊断信息。例如,若是你打错了大括号,以下所示:
awk '$3==0 [print $1}' emp.data
会提示以下错误:
awk: $3==0 [print $1}
awk: ^ syntax error
awk: $3==0 [print $1}
awk: ^ syntax error
复制代码
awk中仅仅只有两种类型 数值、 字符 构成的字符串。一般状况下,一个字段是一个不包含任何空格或制表符的连续字符序列。 当前输入的 行中的第一个字段被称做 $1,第二个是 $2,以此类推。 整个行的内容被定义为 $0。 每一行的字段数量能够不一样。
大都数状况下,咱们仅仅只是打印出其中每一行的某些字段,或者也还须要作一些计算。
若是一个动做没有任何模式,这个动做针对全部输入的行进行操做。 print 语句用来打印(输出)当前输入的行。 因此 {print}
等效于 {print $0}
{print $1,$3}
将输出:
Beth 0
Dan 0
kathy 10
Mark 20
Mary 22
Susie 18
复制代码
在 print 语句中被逗号分隔的表达式,在默认状况下他们将会用一个空格分割来输出。 每一行print生成的内容都会以一个换行符做为结束。但这些默认行为均可以自定义。
AWK 会对当前输入的行有多少字段进行计数,而且将当前行的字段数量存储在一个内建的称为 NF 的变量中。所以 {print NF,$1,$NF}
会打印出 每一行的字段数量、第一个字段的值、最后一个字段的值。 输出:
3 Beth 0
3 Dan 0
3 kathy 10
3 Mark 20
3 Mary 22
3 Susie 18
复制代码
awk 提供了另外一个内建变量, NR。他存储了当前已经读取了多少行的计数。可使用 NR和$0给emp.data的每一行加上行号: {print NR,$0}
输出以下:
1 Beth 4.00 0
2 Dan 3.75 0
3 kathy 4.00 10
4 Mark 5.00 20
5 Mary 5.50 22
6 Susie 4.25 18
复制代码
还能够在字段中间或者计算的值中间打印输出想要的内容: {print "total pay for", $1, "is", $2*$3}
输出以下:
total pay for Beth is 0
total pay for Dan is 0
total pay for kathy is 40
total pay for Mark is 100
total pay for Mary is 121
total pay for Susie is 76.5
复制代码
print 语句可用于快速而简单的输出。若要严格按照你所想的格式化输出,则须要使用 printf 语句。
printf 语句格式以下:
printf(format, value1, value2, ..., valueN)
其中 format 是字符串,包含要逐字打印的文本,穿插在 format 以后的每一个值该如何打印的规格。一个规格是一个 % 符,后面跟着一些字符,用来控制一个 value 的格式。所以,有过少个 value 要打印,在 fromat 中就要有多少个 % 规格。 打印每一个员工的总薪酬: {printf("total pay for %s is $%.2f\n", $1, $2*$3)}
输出以下:
awk '{printf("total pay for %s is $%.2f\n", $1, $2*$3)}' emp.data
total pay for Beth is $0.00
total pay for Dan is $0.00
total pay for kathy is $40.00
total pay for Mark is $100.00
total pay for Mary is $121.00
total pay for Susie is $76.50
复制代码
以薪酬递增的方式输出每一行:
awk '{printf("%6.2f %s\n", $2*$3, $0)}' emp.data | sort
将awk的输出经过管道传给 **sort **命令,输出以下:
0.00 Beth 4.00 0
0.00 Dan 3.75 0
100.00 Mark 5.00 20
121.00 Mary 5.50 22
40.00 kathy 4.00 10
76.50 Susie 4.25 18
复制代码
awk 的模式适用于为进一步的处理从输入中选择相关的数据行。因为不带动做的模式会打印全部匹配的行,因此不少awk程序仅仅包含一个模式。本节将给出一些有用的模式示例。
使用一个对比模式来选择每小时赚5美圆或更多的员工记录,亦即第二个字段大于等于5的行: $2>=5
awk '$2>=5' emp.data
Mark 5.00 20
Mary 5.50 22
复制代码
awk '$2*$3>50 {printf("$%.2f for %s\n", $2*$3, $1)}' emp.data
$100.00 for Mark
$121.00 for Mary
$76.50 for Susie
复制代码
除了数值测试,还能够选择包含特定单词或短语的输入行。这个程序会打印全部第一个字段为 Susie 的行:
$1=="Susie"
操做符 == 用于测试相等性。 也可使用正则表达式的模式查找包含任意任意字母组合,单词或短语的文本。如如下能够匹配到任意位置包含Susie的行: /Susie/
awk '/Susie/' emp.data
Susie 4.25 18
复制代码
可使用括号和逻辑操做符号与&&、或||,以及 非! 对模式进行组合。 $2>=4||$3>=20
会打印第二个字段大于等于4或者第三个字段大于等于20的行:
awk '$2>=4||$3>=20' emp.data
Beth 4.00 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
复制代码
特殊模式 BEGIN 用于匹配第一个输入文件的第一行以前的位置。END 则用于匹配处理过的最后一个文件的最后一行的位置。
这个程序使用 BEGIN 来输出一个标题:
BEGIN {print "Name RATE HOURS"; print ""}
{print}
复制代码
awk 'BEGIN {print "Name RATE HOURS"; print ""}
{print}' emp.data
## 输出以下:
Name RATE HOURS
Beth 4.00 0
Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
复制代码
注意事项:
awk 能够在一行上放多个语句,步过要使用分号;进行分隔。
普通的 print 是打印当前输入行, print "" 则会打印一个空行。
AWK 是按一行一行地读取输入的。
一个动做就是一个以新行或者分号分隔的语句序列。
$3 > 15 {emp = emp + 1}
END {print emp, "employees worked more than 15 hours"}
复制代码
awk '$3 > 15 {emp = emp + 1}
> END {print emp, "employees worked more than 15 hours"}' emp.data
## 输出结果:
3 employees worked more than 15 hours
复制代码
用做数字的 awk 变量的默认初始值为0, 因此不须要初始化 emp。建立一个变量emp初始值为0,若是读入的那一行的第三个字段大于15,则emp在自身值的基础上自增1,读完最后一行后输出存在多少个员工工做时长超过15个小时的语句。
为计算员工数目,可使用内置变量 NR,保存了当前位置读取的行数;在全部输入的结尾它的值就是所读行的总行数。
END {print NR, "employees"}
awk 'END {print NR, "employees"}' emp.data
## 输出结果为:
6 employees
复制代码
以下是一个使用 NR 来计算薪酬均值的程序:
awk '{pay = pay + $2*$3}
> END {print NR, "employees"
> print "total pay is", pay
> print "average pay is", pay/NR
> }' emp.data
## 输出结果为:
6 employees
total pay is 337.5
average pay is 56.25
复制代码
awk 的优点之一是能像大多数语言处理数字同样方便地处理字符串。 awk 能够保存数字也能够保存字符。找出时薪最高的员工:
$2 > maxrate { maxrate = $2; maxemp = $1 }
END { print "highest hourly rate:", maxrate, "for", maxemp }
复制代码
awk '$2 > maxrate { maxrate = $2; maxemp = $1 }
> END { print "highest hourly rate:", maxrate, "for", maxemp }' emp.data
## 输出结果为:
highest hourly rate: 5.50 for Mary
复制代码
awk '{names = names $1 " "}
END {print names}' emp.data
## 输出结果:
Beth Dan kathy Mark Mary Susie
复制代码
虽然在 END 动做中 NR 还保留着它的值, 但 $0 没有。
{last = $0}
END {print last}
复制代码
awk '
> {last = $0}
> END {print last}' emp.data
## 输出结果:
Susie 4.25 18
复制代码
前面已经看到 awk 内置变量用来保存某些频繁使用的数量, NF 表示所在行的总列数, NR 表示当前是第多少行... 还有内置函数用来计算其余有用的数值。除了 平方根、对数、随机数此类的算术函数外,还有操做文本的函数。其中之一是 length 用于计算一个字符串的长度。
awk '{print $1, length($1)}' emp.data
## 输出结果:
Beth 4
Dan 3
kathy 5
Mark 4
Mary 4
Susie 5
复制代码
使用 length、NF、NR来统计输入中行、单词以及字符的数量。为了简便,将每一个字段看做一个单词。
awk ' { nc = nc + length($0) + 1
> nw = nw + NF
> }
> END { print NR, "lines,", nw, "words,", nc, "characters" }' emp.data
## 输出结果为:
6 lines, 18 words, 82 characters
复制代码
由于 $0 不会包含行末的换行符,因此另外加了个1。
awk 为选择提供了一个 if-else 语句, 以及为循环提供了几个语句,它们仅在动做中使用。
以下是一个计算时薪超过6美圆的员工总薪酬与平均薪酬。它使用一个 if 来防范零除问题。
$2 > 6 { n = n+1; pay = pay + $2*$3 }
END {
if(n > 0)
print n, "employees, total pay is", pay,
"average pay is", pay/n
else
print "no employees are paid more than $6/hour"
}
复制代码
awk '$2 > 6 { n = n+1; pay = pay + $2*$3 }
> END {
> if(n > 0)
> print n, "employees, total pay is", pay,
> "average pay is", pay/n
> else
> print "no employees are paid more than $6/hour"
>
> }' emp.data
## 输出结果为:
no employees are paid more than $6/hour
复制代码
注意事项: 咱们可使用一个逗号将一个长语句截断为多行来书写.
{
i = 1
while ( i <=3 ){
# while 循环体(这一行是注释内容)
printf("\t%.2f\n", $1*(1+$2)^i)
i = i + 1
}
}
复制代码
while 后面是圆括号,里面是布尔表达式。 循环体是条件后大括号包围的语句。 ^ 是指数操做符。 # 后面是注释。
演示1000美圆,利率为6%与12%,5年的复利分别是如何增加的:
awk ' > { > i = 1 > while ( i <=5 ){ > # while 循环体(这一行是注释内容) > printf("\t%.2f\n", $1*(1+$2)^i) > i = i + 1 > } > } > '
1000 .06 5
1060.00
1123.60
1191.02
1262.48
1338.23
1000 .12 5
1120.00
1254.40
1404.93
1573.52
1762.34
复制代码
使用for循环实现上述例子:
awk '
> {
> for( i = 1; i <= $3; i = i+1 ){
> printf("\t%.2f\n", $1*(1+$2)^i)
> }
> }
> '
1000 .06 5
1060.00
1123.60
1191.02
1262.48
1338.23
1000 .12 5
1120.00
1254.40
1404.93
1573.52
1762.34
复制代码
awk 为存储一组相关的值提供了数组,虽然数组给予了awk很强的能力,可是在这里咱们仅仅展现一个简单的例子。 第一个动做将输入行存为数组 line 的连续元素; 第一行放在line[1],第二行放在line[2]。 END 动做使用一个while语句从后往前打印数组中的输入行:
# 反转-按行逆序打印输入
{line[NR] = $0}
END {
i = NR
while(i > 0){
print line[i]
i = i-1
}
}
复制代码
awk '
> {line[NR] = $0}
>
> END {
> i = NR
> while(i > 0){
> print line[i]
> i = i-1
> }
> }' emp.data
# 输出结果为:
Susie 4.25 18
Mary 5.50 22
Mark 5.00 20
kathy 4.00 10
Dan 3.75 0
Beth 4.00 0
复制代码
-dump-variables[=file] 操做能够打印全局变量到文件中,默认是“awkvars.out”文件。
awk --dump-variables ''
# 查看文件awkvars.out
cat awkvars.out
ARGC: number (1)
ARGIND: number (0)
ARGV: array, 1 elements
BINMODE: number (0)
CONVFMT: string ("%.6g")
ERRNO: number (0)
FIELDWIDTHS: string ("")
FILENAME: string ("")
FNR: number (0)
FS: string (" ")
IGNORECASE: number (0)
LINT: number (0)
NF: number (0)
NR: number (0)
OFMT: string ("%.6g")
OFS: string (" ")
ORS: string ("\n")
RLENGTH: number (0)
RS: string ("\n")
RSTART: number (0)
RT: string ("")
SUBSEP: string ("\034")
TEXTDOMAIN: string ("messages")
复制代码
awk --help
# 输出信息以下:
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options: GNU long options:
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
-m[fr] val
-O --optimize
-W compat --compat
-W copyleft --copyleft
-W copyright --copyright
-W dump-variables[=file] --dump-variables[=file]
-W exec=file --exec=file
-W gen-po --gen-po
-W help --help
-W lint[=fatal] --lint[=fatal]
-W lint-old --lint-old
-W non-decimal-data --non-decimal-data
-W profile[=file] --profile[=file]
-W posix --posix
-W re-interval --re-interval
-W source=program-text --source=program-text
-W traditional --traditional
-W usage --usage
-W use-lc-numeric --use-lc-numeric
-W version --version
To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.
gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.
Examples:
gawk '{ sum += $1 }; END { print sum }' file
gawk -F: '{ print $1 }' /etc/passwd
复制代码
awk --version
# 输出结果以下:
GNU Awk 3.1.7
Copyright (C) 1989, 1991-2009 Free Software Foundation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
复制代码
-v 操做容许给一个变量分配值。容许在程序执行以前分配。
awk -v name=LFF 'BEGIN {printf("username=%s\n", name)}'
# 输出结果为:
username=LFF
复制代码
--lint 操做容许输出检查信息,好比当参数提供错误,会将警告信息看成错误。
awk --lint '' /bin/ls
# 输出结果为:
awk: warning: empty program text on command line
awk: warning: source file does not end in newline
awk: warning: no program text at all!
复制代码
匹配输入行中包含字符a的行,所有输出。
awk '/a/ {print $0}' emp.data
# 输出结果为:
Dan 3.75 0
kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
复制代码
打印输入行中包含字符a的行数:
awk '/a/ {++cnt} END {print "匹配的行数为:", cnt}' emp.data
# 输出结果为:
匹配的行数为: 4
复制代码
shell awk 'BEGIN {print "Arguments =", ARGC}' One Two Three Four Arguments = 5
awk 'BEGIN {
> for (i = 0; i < ARGC - 1; ++i) {
> printf "ARGV[%d] = %s\n", i, ARGV[i]
> }
> }' one two three four
# 输出结果为:
ARGV[0] = awk
ARGV[1] = one
ARGV[2] = two
ARGV[3] = three
复制代码
表示数字的转换格式。默认值是 %.6g。
awk 'BEGIN { print "Conversion Format =", CONVFMT }'
#输出:
Conversion Format = %.6g
复制代码
awk 'BEGIN { print ENVIRON["USER"] }'
# 输出当前用户
deploy
复制代码
咱们能够借助env命令查看linux服务器上的所有环境变量:
env
# 查看当前服务器上的全部环境变量
HOSTNAME=sz-local3
TERM=vt100
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.89.4.224 53217 22
QTDIR=/usr/lib64/qt-3.3
OLDPWD=/data/app
QTINC=/usr/lib64/qt-3.3/include
SSH_TTY=/dev/pts/0
GREP_OPTTIONS=--color=always
USER=deploy
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/deploy
PATH=/usr/lib/jdk1.7.0_76/bin:/usr/lib64/qt-3.3/bin:/data/app/node-v4.2.4-linux-x64/bin:/usr/lib/jdk1.7.0_76/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/deploy/bin
PWD=/data/app/lff
JAVA_HOME=/usr/lib/jdk1.7.0_76
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/home/deploy
LOGNAME=deploy
QTLIB=/usr/lib64/qt-3.3/lib
CVS_RSH=ssh
CLASSPATH=/usr/lib/jdk1.7.0_76/lib:/usr/lib/jdk1.7.0_76/lib:
SSH_CONNECTION=10.89.4.224 53217 10.193.1.27 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
复制代码
awk 'END {print FILENAME}' emp.data
# 输出结果为:
emp.data
复制代码
FS 表示文件分割符,默认是空白字符。也可使用 -F 命令行变动。
awk 'BEGIN {print "FS = " FS}' | cat -vte
# 输出结果为:
FS = $
复制代码
表示匹配函数 match 到的字符串的长度。
awk '
BEGIN {
if(match("One Two Three", "re")){
print RLENGTH
}
}'
# 匹配到了Three中的re,输出结果为:
2
复制代码
awk ' BEGIN { if(match("One Two Three There", "re")){ print RSTART } }'
# 从O开始,到Three的r,位置处于11,输出结果为:
11
复制代码
awk 'BEGIN {print PROCINFO["pid"]}'
5142
复制代码
awk 'BEGIN {print ++a}'
# 先自增,输出结果为:
1
# 后自增,输出结果为:
awk 'BEGIN {print a++}'
0
复制代码
awk 'BEGIN {print --a}'
-1
awk 'BEGIN {print a--}'
0
复制代码
awk 'BEGIN {print cnt+=10; print cnt}'
10
10
awk 'BEGIN {cnt=10 ;print cnt*=10; print cnt}'
100
100
awk 'BEGIN {cnt=10 ;print cnt-=10; print cnt}'
0
0
awk 'BEGIN {cnt=10 ;print cnt/=10; print cnt}'
1
1
awk 'BEGIN {cnt=10 ;print cnt%=10; print cnt}'
0
0
awk 'BEGIN {cnt=10 ;print cnt^=10; print cnt}'
10000000000
10000000000
awk 'BEGIN {cnt=10 ;print cnt**=10; print cnt}'
10000000000
10000000000
复制代码
空白字符是字符串链接符
awk 'BEGIN {a="hello, "; b="world!"; c= a b; print(c)}'
# 输出链接结果
hello, world!
复制代码
for in 操做经常使用于遍历数组。
awk '
> BEGIN { arr[1] = "a"; arr[2] = "b"; arr[3] = "c";
> for(i in arr){
> print("a[", i, "]=", arr[i])
> }
> }'
# 遍历输出数组元素:
a[ 1 ]= a
a[ 2 ]= b
a[ 3 ]= c
复制代码
示例:
echo -e "cat\nbat\nfun\nfin\nfan" | awk '/f.n/'
fun
fin
fan
复制代码
匹配 The 开头的字符串:
echo -e "This\nThat\nThere\nTheir\nthese" | awk '/^The/'
There
Their
复制代码
匹配 n 结尾的字符串:
echo -e "knife\nknow\nfun\nfin\nfan\nnine" | awk '/n$/'
fun
fin
fan
复制代码
匹配 Call 或者 Tall:
echo -e "Call\nTall\nBall" | awk '/[CT]all/'
Call
Tall
复制代码
使用^排除,匹配不是 Call且不是Tall的字符串:
echo -e "Call\nTall\nBall" | awk '/[^CT]all/'
Ball
复制代码
匹配 Call 或者 Tall
echo -e "Call\nTall\nBall\nSmall\nShall" | awk '/Call|Ball/'
Call
Ball
复制代码
echo -e "Colour\nColor" | awk '/Colou?r/'
Colour
Color
复制代码
echo -e "ca\ncat\ncatt" | awk '/cat*/'
ca
cat
catt
复制代码
echo -e "Apple Juice\nApple Pie\nApple Tart\nApple Cake" | awk
'/Apple (Juice|Cake)/'
Apple Juice
Apple Cake
复制代码
awk 'BEGIN {
fruits["mango"] = "yellow";
fruits["orange"] = "orange"
print fruits["orange"] "\n" fruits["mango"]
}'
orange
yellow
复制代码
awk 'BEGIN {
fruits["mango"] = "yellow";
fruits["orange"] = "orange";
delete fruits["orange"];
for(i in fruits){print fruits[i]}
}'
# 删除orange后,只剩下yello
yellow
复制代码
100 200 300
400 500 600
700 800 900
复制代码
array[0][0] 存储 100,array[0][1] 存储 200。 正确的语法是 array["0,0"] = 100
awk 'BEGIN {
array["0,0"] = 100;
array["0,1"] = 200;
array["0,2"] = 300;
array["1,0"] = 400;
array["1,1"] = 500;
array["1,2"] = 600;
# print array elements
print "array[0,0] = " array["0,0"];
print "array[0,1] = " array["0,1"];
print "array[0,2] = " array["0,2"];
print "array[1,0] = " array["1,0"];
print "array[1,1] = " array["1,1"];
print "array[1,2] = " array["1,2"];
}'
复制代码
子串 substr 出如今字符串 str 中的开始位置,从1开始计数。
awk 'BEGIN {print index("Hello", "ll")}'
3
复制代码
正则匹配 regex,将其替换为 sub指定的内容, string是所选的字符串。
awk 'BEGIN { str = "Hello,World!"; gsub("World", "Lily", str); print str}'
Hello,Lily!
复制代码
匹配则返回regex在str中的起始位置,不然返回0表示没有匹配到。
awk 'BEGIN {str = "Hello,world!"; ret = match(str, "wo"); print str, ret}'
Hello,world! 7
复制代码
将 str 按 regex 匹配拆分,获得的每一个拆分做为元素保存在 arr 数组中。
awk 'BEGIN {str = "Hello,Hellokitty"; split(str, arr, ",");
for(ele in arr){
print arr[ele]
}}'
Hello
Hellokitty
复制代码
将字符串强转成数值类型, str开头是0的话会转为八进制, 是0x或0X开头的话会转为十六进制。
awk 'BEGIN {
> print "Decimal num = " strtonum("123")
> print "Octal num = " strtonum("0123")
> print "Hexadecimal num = " strtonum("0x123")
> }'
Decimal num = 123
Octal num = 83
Hexadecimal num = 291
复制代码
获取字串,从字符串 str 中的 start位置开始截取长度为 L 的字符串。
awk 'BEGIN {str = "nihaoya!"; print substr(str, 1, 2)}'
ni
复制代码
将字符串 str 小写化。
awk 'BEGIN{ print tolower("HeLLo")}'
hello
复制代码
将字符串 str 大写化。
awk 'BEGIN{ print toupper("HeLLo")}'
HELLO
复制代码
获取自 1970-01-01 00:00:00 至今的unix时间戳
awk 'BEGIN {print systime()}'
1545742584
复制代码
将指定的日期格式串转换为时间戳,datespec 格式是 YYYY mm dd HH MM SS
awk 'BEGIN {print mktime("2018 12 25 21 07 00")}'
1545743220
复制代码
将时间戳 timestamp 转换成指定格式format的字符串
awk 'BEGIN {
> print strftime("Time = %m/%d/%Y %H:%M:%S", systime())
> }'
Time = 12/25/2018 21:11:09
复制代码
按位与
awk 'BEGIN {
num1 = 10
num2 = 6
printf "(%d AND %d) = %d\n", num1, num2, and(num1, num2)
}'
# 输出结果为:
(10 AND 6) = 2
复制代码
将num按位左移size位数, 左移一位至关于乘以2
awk 'BEGIN {print lshift(10, 1)}'
20
复制代码
将num按位右移size位数, 右移一位至关于除以2
awk 'BEGIN {print rshift(10, 1)}'
5
复制代码
awk 'BEGIN {
num1 = 10
num2 = 6
printf "(%d OR %d) = %d\n", num1, num2, or(num1, num2)
}'
# 输出结果为:
(10 OR 6) = 14
复制代码
awk 'BEGIN {
num1 = 10
num2 = 6
printf "(%d XOR %d) = %d\n", num1, num2, xor(num1, num2)
}'
# 输出结果为:
(10 XOR 6) = 12
复制代码
语法形式:
function function_name(argument1, argument2, ...) {
function body
}
复制代码
示例:
# Returns minimum number
function find_min(num1, num2){
if (num1 < num2)
return num1
return num2
}
# Returns maximum number
function find_max(num1, num2){
if (num1 > num2)
return num1
return num2
}
# Main function
function main(num1, num2){
# Find minimum number
result = find_min(10, 20)
print "Minimum =", result
# Find maximum number
result = find_max(10, 20)
print "Maximum =", result
}
# Script execution starts here
BEGIN {
main(10, 20)
}
复制代码
咱们还能够将数据导入到文件中。在 print 或者 printf 后增长重定向的文件语句。 语法:
print data > outputfile
将数据 data 写入到 outputfile,若是 outputfile 不存在则建立。当指定重定向时,文件 output 会清除全部内容,而后写入数据。顺序写操做则不会提早清除文件内容,只是追加。
# 将 "Old data" 写入 message.txt 文件中,没有则建立 message.txt 文件。
echo "Old data" > message.txt
# 查看文件内容
cat message.txt
# 输出结果:
Old data
复制代码
而后执行:
awk 'BEGIN {print "Hello,World!" > "message.txt"}'
cat message.txt
# 文件的旧内容清楚了,内容已经被替换
Hello,World!
复制代码
print DATA >> output-file
echo "Old data" > /tmp/message.txt
cat /tmp/message.txt
# 查看文件内容
Old data
# 追加内容到文件中
awk 'BEGIN { print "Hello, World !!!" >> "/tmp/message.txt" }'
cat /tmp/message.txt
# 输出内容:
Old data
Hello, World !!!
复制代码
可能须要发送输出数据到其它程序,经过管道而不是文件。 这种转移方式会打开一个管道命令,而且会经过管道将数据项经过管道传到另外一个进程去执行命令。 转移参数是一个 awk 表达式。
管道的语法以下:
print items | command
示例:使用 tr 命令将小写转换为大写
awk 'BEGIN { print "hello, world !!!" | "tr [a-z] [A-Z]" }'
HELLO, WORLD !!!
复制代码
更过关于 tr 的使用方法,可使用 tr --help 查看帮助信息。
awk 能够经过 |& 跟外部进程通讯。
awk 'BEGIN {
> cmd = "tr [a-z] [A-Z]"
> print "hello, world !!!" |& cmd
> close(cmd, "to")
>
> cmd |& getline out
> print out;
> close(cmd);
> }'
HELLO, WORLD !!!
复制代码
说明:
awk 'BEGIN { printf "Hello\nWorld\n" }'
# 输出结果为:
Hello
World
复制代码
awk 'BEGIN { printf "Sr No\tName\tSub\tMarks\n" }'
Sr No Name Sub Marks
复制代码
awk 'BEGIN { printf "Sr No\vName\vSub\vMarks\n" }'
# 输出结果为:
Sr No
Name
Sub
Marks
复制代码
awk 'BEGIN { printf "Field 1\rField 2\rField 3\rField 4\n" }'
输出:
Field 4
复制代码
awk 'BEGIN { printf "Sr No\fName\fSub\fMarks\n" }'
Sr No
Name
Sub
Marks
复制代码
awk 'BEGIN { printf "ASCII value 65 = character %c\n", 65 }'
ASCII value 65 = character A
复制代码
awk 'BEGIN { printf "Percentags = %d\n", 80.66 }'
输出结果为:
Percentags = 80
复制代码
awk 'BEGIN { printf "Percentags = %E\n", 80.66 }'
输出结果为:
Percentags = 8.066000e+01
复制代码
awk 'BEGIN { printf "Percentags = %f\n", 80.66 }'
输出结果为:
Percentags = 80.660000
复制代码
awk 'BEGIN { printf "Name = %s\n", "Sherlock Holmes" }'
输出结果为:
Name = Sherlock Holmes
复制代码
awk 'BEGIN {
num1 = 10; num2 = 20; printf "Num1 = %10d\nNum2 = %10d\n", num1, num2
}'
# 输出结果为:
Num1 = 10
Num2 = 20
复制代码
AWK 是一种解释性编程语言。是专门为处理文本而设计的。名字是来自于设计者的名字 —— Alfred Aho, Peter Weinberger, and Brian Kernighan.
描述如何在 GNU/Linux 系统中安装 AWK 环境。
通常状况下, AWK 默认在大都数 GNU/Linux 系统中都是安装发行的。 你可使用 which 命令,检查awk在系统中是否安装好了。 若是没有安装 awk, 能够按以下命令借助 高级安装包 APT安装 AWK:
sudo apt-get update
sudo apt-get install gawk
复制代码
yum install gawk
# 查看
which awk
# 输出结果为:
/bin/awk
复制代码
从源代码中安装: