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="
---
"} {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 "----
Total 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是变量名,存放数组的索引

原文地址:https://www.cnblogs.com/NewMan13/p/11121901.html