Awk命令
1.Awk命令语法
1.1 执行单个命令
awk的基本语法:
awk -Fs '/pattern/ {action}' input-file
-F为字段分界符,如果不指定,则默认空格为分隔符
/pattern/ 和{action}需要用单引号包起来,/pattern/是可选的,如果没有,则默认对所有行都执行action.如果指定,则只对匹配的行执行action
例如:
$awk -F":" '/mail/ {print $1}' /etc/passwd mail
1.2 执行批量命令
如果需要执行多个命令,则可以把多个命令放在一个文件中,然后使用-f执行。
awk –Fs –f myscript.awk input-file
1.3 awk命令结构
典型的awk命令包含三部分:
(1) BEGIN区域
BEGIN区域只会在body区域执行前执行一次.
BEGIN区域的语法:BEGIN {awk-commands}
(2)body区域
body 区域的命令每次从输入文件读取一行就会执行一次
body区域的语法: /pattern/ {awk-commands}
(3)END区域
END区域会在body区域执行完后执行一次。
END区域的语法:END {awk-commands}
例如:
$awk 'BGEIN {FS=":";print "------"} /mail/ {print $1} END {print "----footer----"}' /etc/passwd _mailman:*:78:78:Mailman _clamav:*:82:82:ClamAV _amavisd:*:83:83:AMaViS ----footer----
2.awk命令
2.1 打印命令
默认情况下,awk 的打印命令 print(不带任何参数)会打印整行数据。
例如:
$awk '{print}' employee.txt 101,Jonny Doe,CEO 102,Jason Smith,IT Manager 103,Raj Reddy,Sysadmin 104,Anand Ram,Developer 105,Jane Miller,Sales Manager
也可以传递变量"$字段序号"作为参数,打印指定的字段。例如:
$awk '{print $1}' employee.txt 101,Jonny 102,Jason 103,Raj 104,Anand 105,Jane
$0 表示整行, $1表示第一个字段,$n表示第n个字段。
当然,也可以通过-F指定分隔符。例如:
$awk -F"," '{print $2}' employee.txt Jonny Doe Jason Smith Raj Reddy Anand Ram Jane Miller
2.2 模式匹配
可以只在匹配特殊模式的行执行awk命令。例如:
$awk -F"," '/Manager/ {print $2, $3}' employee.txt Jason Smith IT Manager Jane Miller Sales Manager
3. awk内置变量
awk有很多内置标量,我们可以在脚本中直接使用。
(1)FS
awk默认的字段分隔符是空格,现在你也知道,如果要指定字段分隔符,可以使用-F选项来指定它。
同样的事情可以使用awk内置变量FS来完成,比如:
$awk 'BEGIN {FS=","} /Manager/ {print $2, $3}' employee.txt Jason Smith IT Manager Jane Miller Sales Manager
FS可以同时指定多个分隔符:
例如有如下文件:
cat employee-fs.txt 101,John Doe:CEO%10000 102,Jason Smith:IT Manager%5000 103,Raj Reddy:Sysadmin%4500 104,Anand Ram:Developer%4500 105,Jane Miller:Sales Manager%3000
现在要以",:%"作为分隔符,如下所示:
awk 'BEGIN {FS="[,:%]"} {print $2,$3}' employee-fs.txt John Doe CEO Jason Smith IT Manager Raj Reddy Sysadmin Anand Ram Developer Jane Miller Sales Manager
(2) OFS-输出字段分隔符
FS 是输入字段分隔符,OFS 是输出字段分隔符。OFS 会被打印在输出行的连续的字段之间。
默认情况下,awk 在输出字段中间以空格分开。例如:
$awk -F"," 'BEGIN {OFS=":"} {print $2, $3}' employee.txt Jonny Doe:CEO Jason Smith:IT Manager Raj Reddy:Sysadmin Anand Ram:Developer Jane Miller:Sales Manager
请注意在 print 语句中使用和不使用逗号的细微差别(打印多个变量时).当在 print 语句中 指定了逗号,awk 会使用 OFS
(3) RS-记录分隔符
假如有下面文件:
101,John Doe:102,Jason Smith:103,Raj Reddy
上面每个员工信息使用冒号分隔的,我们可以指定记录分隔符,例如:
awk 'BEGIN {RS=":";FS=","} {print $1}' employ-one-line.txt 101 102 103
(4)ORS-输出记录分隔符
RS输入记录分隔符,ORS是输出记录分隔符
awk 'BEGIN {FS=",";ORS="\n---\n"} {print $2,$3}' employee.txt Jonny Doe CEO --- Jason Smith IT Manager --- Raj Reddy Sysadmin --- Anand Ram Developer --- Jane Miller Sales Manager ---
(5) NR和FNR
NR表示当前记录所在的行号。
FNR和NR什么区别呢?如果awk命令传入两个输入文件,NR会在第二个文件继续新增,FNR在第二个文件会从1开始记录。
awk 'BEGIN {FS=","} {print "Emp id of record number", NR, "is", $1} END {print "Total number of records:", NR}' employee.txt Emp id of record number 1 is 101 Emp id of record number 2 is 102 Emp id of record number 3 is 103 Emp id of record number 4 is 104 Emp id of record number 5
(6) FILENAME-当前处理的文件名
(7) NF-表示当前行的字段数
4.awk变量及操作符
4.1 变量
awk变更可以直接使用,而无需申明。如果要初始化变量,最好在BEGIN区域内执行初始化。
awk没有数据类型的概念。
下面看下在awk中如何使用变量:
cat employee-sal.txt 101,John Doe,CEO,10000 102,Jason Smith,IT Manager,5000 103,Raj Reddy,Sysadmin,4500 104,Anand Ram,Developer,4500 105,Jane Miller,Sales Manager,3000
awk 'BEGIN {FS=",";total=0} {print $2 " salary is: " $4;total+=$4} END {print "----\nTotal company salary=$" total}' employee-sal.txt John Doe salary is: 10000 Jason Smith salary is: 5000 Raj Reddy salary is: 4500 Anand Ram salary is: 4500 Jane Miller salary is: 3000 ---- Total company salary=$27000
4.2 操作符
(1)一元操作符
只接受单个操作数的操作符叫做一元操作符.
awk -F, '{print ++$4}' employee-sal.txt 10001 5001 4501 4501 3001
(2)算术操作符
下面是算术操作符:
(3) 赋值操作符
(4) 比较操作符
下面的例子中,如果不指定操作,awk会打印符合条件的整条记录。
$ awk -F ',' '$5 <= 5' items.txt 102,Refrigerator,appliance,850,2 105,Laser Printer,Office,475,5
打印编号为103的商品信息:
$awk -F"," '$1 == 103' items.txt 103,Mp3 Player,Audio,270,15
使用&&比较两个条件
awk -F',' '$4 < 900 && $5 <= 5 {print $2}' items.txt Refrigerator Laser Printer
(5) 正则表达式操作符
使用“==”时,awk精确匹配。可以使用"~"来做模糊匹配。
例如:
#使用"=="是精确匹配 awk -F"," '$2 == "Tennis"' items.txt #使用"~"是模糊匹配 awk -F"," '$2 ~ "Tennis"' items.txt 104,Tennis Racket,Sports,190,20
!~即为不匹配。
5. awk分支和循环
awk支持条件判断,控制程序流程。大部分条件判断语句和C语言差不多。
5.1 if结构
if结构语法如下:
if(conditional-expression) { action1; action2; }
如果条件为真,则会执行{}中的语句。当所有语句执行完后,awk继续执行后面的语句。
例如:
awk -F',' '{if (($4 >= 500 && $4 <= 1000) && ($5 <= 5)) print "Only", $5, "qty of", $2, "is available"}' items.txt Only 2 qty of Refrigerator is available
5.2 if else结构
语法:
if (conditional-expression) { action1 } else { action2 }
例如:
$ cat if-else.awk BEGIN { FS="," } { if($5 <= 5) { print "Buy More:Order", $2, "immediately" } else { print "shell More:Give discount on", $2, "immediately" } }
执行结果如下:
$ awk -f if-else.awk items.txt shell More:Give discount on HD Camcorder immediately Buy More:Order Refrigerator immediately shell More:Give discount on MP3 Player immediately shell More:Give discount on Tennis Racket immediately Buy More:Order Laser Printer immediately
5.3 while结构
语法如下:
while(condition) actions
while首先检查condition, 如果为true,则执行actions, 执行完actions, 再检查condition, 如果是true, 再次执行actions, 直到condition为false, 退出循环。
也可以使用do...while.....循环:
do action while(condition)
5.4 for循环
语法:
for(initialization;condition;increment/decrement)
例如:
echo "1 2 3 4" | awk '{ for (i=1;i<=NF;i++) total = total + $i } END { print total }' 10
5.5 break, continue,exit
6.awk数组
6.1 数组语法
语法:
arrayname[string]=value
- arrayname 是数组名称
- string 是数组索引
- value是为数组元素赋的值
6.2 引用数组元素
要访问awk数组中某个特定元素,使用arrayname[idnex]即可返回该索引中的值。
注意:如果试图访问一个不存在的数组元素,awk会自动以访问时指定的索引建立该元素,并赋予null值。
(1)
if(index in array-name)
可以检测元素是否存在
(2)
for (var in arrayname)
可以遍历awk数组
var是变量名,存放数组的索引