awk简介

awk: 中文意思是报告生成器 能够根据我们输入的信息,将信息格式化以后显示,将定义好的信息以比较美观(直观)的方式显示出来出现比较早,继而出现了new awk(nawk)在windows上实现,gawk, awk实现在linux上。awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字母,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本,它提供

了Bell实验室和GNU的一些扩展。下面就对awk进行介绍。

awk使用的基本格式:

1
2
3
# awk [options] 'script' file1 file2, ...
# awk [options] 'PATTERN { action }' file1 file2, ...细化了上面的组合
常用的命令:print(输出), printf(打印)

awk工作过程

根据我们所定义的模式,一次从文件中读取一行文本,awk会对取出的文本做相应的切片,将每一行按照分隔符进行切割,假如我们有一行文本: this is a test.它会使用空白字符当做分隔符,将它们各个分开,切割成了四个片,分别为: this is a test.这四个片,可以使用变量,分别对应为$1,$2,$3,$4代表四个切割片,下面就做一个演示,看如何实现awk的强大功能

一、awk的输出:print

1
2
print的使用格式:
print item1, item2, ...

输出要点:

1、各项目之间使用逗号隔开,而输出时则以空白字符分隔;

2、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;

3、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";

实例分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
显示整个文本(注意,这里只是测试,所以只有一行)
#  awk '{print $N}' test.txt
this is a test.
# awk '{print $0}' test.txt
this is a test.
显示文本的一行中的第一个参数
# awk '{print $1}' test.txt
this
显示文本的一行中的第二个参数
# awk '{print $2}' test.txt
is
显示文本的一行中的第四个参数
# awk '{print $4}' test.txt
test.
显示文本的一行中的第一与第二个个参数
# awk '{print $1,$2}' test.txt
this is
显示文本的一行中的第一个与第二个参数,中间可以加#号
# awk 'BEGIN{OFS="#"}{print $1,$2}' test.txt
this#is
显示文本中的各个参数,还可以加修饰符
# awk 'BEGIN{OFS=":"}{print $1,$2,$3,$4}' test.txt
this:is:a:test.
显示文本中的参数,还可以加修饰符,还可以加字符串
#  awk 'BEGIN{OFS=":"}{print $1,"hello",$2}' test.txt
this:hello:is
输出三行,注意换行需要加\n
# awk 'BEGIN { print "line one\nline two\nline three" }'
line one
line two
line three

二、awk变量

2.1 awk内置变量之记录变量:

1
2
3
4
FS: field separator,读取文本时所使用的字段分隔符
RS: Record separator,读取文本信息所使用的换行符
OFS: Output Filed Separator: 输出文本时使用的字段分隔符
ORS:Output Row Separator:输出文本时使用的行分隔符

2.2 awk内置变量之数据变量:

NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;

NF:Number of Field,当前记录的field个数;

FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;

实例分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
显示文本的行数
# awk '{print NR}' test.txt
1
显示一行总共有几个参数
# awk '{print NF}' test.txt
4
显示文本的最后一个参数
# awk '{print $NF}' test.txt
test.
同时查看多个文本
# awk '{print FNR}' test.txt /etc/fstab
1  显示的是第一个文本的行数
1  显示的是第二个文本的第一行数,一此类推
2  显示的是第二个文本的第二行数
3  显示的是第二个文本的第三行数

ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;

ARGC: awk命令的参数的个数;

FILENAME: awk命令所处理的文件的名称;

ENVIRON:当前shell环境变量及其值的关联数组;

1
2
3
4
查看环境变量
# awk 'BEGIN{print ENVIRON["PATH"]}'
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/
bin:/usr/sbin:/usr/bin:/usr/local/apache/bin:/usr/local/mysql/bin:/root/bin

2.3 用户自定义变量

gawk允许用户自定义自己的变量以便在程序代码中使用,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头。gawk变量名称区分字符大小写。

2.3.1 在脚本中赋值变量

在gawk中给变量赋值使用赋值语句进行

2.3.2 在命令行中使用赋值变量

gawk命令也可以在“脚本”外为变量赋值,并在脚本中进行引用。

实例分析:

1
2
3
4
5
输出一个变量,并赋值
# awk 'BEGIN{var="variable testing";print var}'
variable testing
# awk -v var="variable testing" 'BEGIN{print var}'
variable testing

三、awk打印工具:printf

1
2
printf命令的使用格式:
printf format, item1, item2, ...

printf要点:

1、其与print命令的最大不同是,printf需要指定format;

2、format用于指定后面的每个item的输出格式;

3、printf语句不会自动打印换行符;需要添加\n

format格式的指示符都以%开头,后跟一个字符;如下:

%c: 显示第一个参数的第一个字符

%d, %i:十进制整数;

%e, %E:科学计数法显示数值;

%f: 显示浮点数;

%g, %G: 以科学计数法的格式或浮点数的格式显示数值;

%s: 显示字符串;

%u: 无符号整数;

%%: 显示%自身;

修饰符:

N: 显示宽度;

-: 左对齐;

+:显示数值符号;

举例分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# awk '{printf "%c\n",$1}' test.txt
t 显示第一个参数的第一个字母
# awk '{printf "%s\n",$1}' test.txt
this  显示第一个参数
# awk '{printf "%10s\n",$1}' test.txt
      this 显示时用了10个字符串,默认是右对齐
# awk '{printf "%-10s\n",$1}' test.txt
this  显示时左对齐,后面有6个空字符串
# awk '{printf "%-10s,%-10s\n",$1,$2}' test.txt
this      ,is
# awk '{printf "%-10s%-10s\n",$1,$2}' test.txt
this      is 
# awk -F: '{printf "%5d",$3}' /etc/passwd
    0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   99   81   28   69   77   38   70   32   47   51   74   16   68  100   2965534   43   42  500  501  502  503 2002 2003 2004 4004 2033 2034 4005 4006 4007 4011 4017 4018 4019 4026 4027 4028   48   25  101
# awk -F: '{printf "%-5d\n",$3}' /etc/passwd   左对齐
# awk -F: '{printf "%+5d\n",$3}' /etc/passwd   右对齐
# awk -F: '{printf "%-15s %i\n",$1,$3}' test.txt
this is a test. 0

四、输出重定向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
print items > output-file
print items >> output-file
print items | command
特殊文件描述符:
/dev/stdin:标准输入
/dev/sdtout: 标准输出
/dev/stderr: 错误输出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0
例子:
# awk -F: '{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd
root            0
bin             1
daemon          2
adm             3
lp              4
sync            5
shutdown        6
halt            7

五、awk的操作符:

5.1 算术操作符:

-x: 负值

+x: 转换为数值;

x^y:

x**y: 次方

x*y: 乘法

x/y:除法

x+y:

x-y:

x%y:

5.2 字符串操作符:

只有一个,而且不用写出来,用于实现字符串连接;

5.3 赋值操作符:

=、+=、-=、*=、/=、%=、^=、**=、++、--

需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;

5.4 布尔值

awk中,任何非0值或非空字符串都为真,反之就为假;

5.5 比较操作符:

1
2
3
4
5
6
7
8
9
10
x < y      x小于y为真,反之为假
x <= y     x小于等于y为真,反之为假
x > y      x大于y为真,反之为假
x >= y     x大于等于y为真,反之为假
x == y    x恒等于y为真,反之为假
x != y    x不等于y为真,反之为假
x ~ y   True if the string x matches the regexp denoted by y.
x !~ y  True if the string x does not match the regexp denoted by y.
subscript in array    True if the array array has an element with the
subscript subscript.

5.5 表达式间的逻辑关系符:

&&: 逻辑与

|| :逻辑或

5.6 条件表达式:相当于if语句

1
2
3
4
举例:若a大于b,则取a is max,反之取b is max
a=3
b=4
a>b?a is max:b is max

5.7 函数调用:

function_name (para1,para2)

六、awk的模式:

awk 'program' input-file1 input-file2 ...

其中的program为:

pattern { action }

pattern { action }

...

6.1 常见的模式类型:

1、Regexp: 正则表达式,格式为/regular expression/

1
2
3
4
5
例如:显示以r开头的行
# awk -F: '/^r/{print $1}' /etc/passwd
root
rpc
rpcuser

2、expresssion:表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符~(匹配)和~!(不匹配)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
例题:
显示id号小于等于2的用户和id号
# awk -F: '$3-1<5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
# awk -F: '$3<=5{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
取出默认shell为bash的用户
# awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd
root /bin/bash
student /bin/bash
visitor /bin/bash
myuseradd /bin/bash
显示默认shell不是bash的用户
# awk -F: '$7!~"bash"{print $1,$7}' /etc/passwd
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin

3、Ranges: 指定的匹配范围,格式为pat1,pat2

1
2
3
4
显示id号为0或者shell为/sbin/nologin的用户
# awk -F: '$3==0,$7~"nologin"{print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin

4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# awk -F: '$3==0,$7~"nologin"{printf "%-10s%-20s\n",$1,$7}' /etc/passwd
root      /bin/bash         
bin       /sbin/nologin
可以在显示时显示表头
# awk -F: 'BEGIN{print "Username shell"}{printf "%-10s%-20s\n",$1,$7}' /etc/passwd
Username      shell
root      /bin/bash         
bin       /sbin/nologin     
daemon    /sbin/nologin     
adm       /sbin/nologin
显示表头和表尾
#  awk -F: 'BEGIN{print "Username  shell"} {printf "%-10s%-20s\n",$1,$7}END
{print "END OF report"}' /etc/passwd
Username      shell
root      /bin/bash         
bin       /sbin/nologin     
daemon    /sbin/nologin     
adm       /sbin/nologin  
END OF report

5、Empty(空模式):匹配任意输入行,对文件中的每一行做匹配

1
2
3
4
5
# awk -F:  '{printf "%-10s%-20s\n",$1,$7}' /etc/passwd
root      /bin/bash         
bin       /sbin/nologin     
daemon    /sbin/nologin     
adm       /sbin/nologin

6.2 常见的Action(动作)

1
2
3
4
5
1、Expressions:表达式
2、Control statements:控制语句(ifwhile...dofor....等待)
3、Compound statements:复合语句
4、Input statements:输入语句
5、Output statements:输出语句

/正则表达式/:使用通配符的扩展集。

关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个

字段比第一个字段长的行。

模式匹配表达式:

模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。

BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。

END:让用户在最后一条输入记录被读取之后发生的动作。

七、控制语句:

7.1 if-else

语法:if (condition) {then-body} else {[ else-body ]}

实例分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
若用户是root则显示“admin”否则显示为“Common user”
# awk -F: '{if ($1=="root") print $1,"admin"; else print $1, "Common user"}' /etc/passwd
root admin
bin Common user
daemon Common user
adm Common user
lp Common user
这是对上面的语法格式化了,看起来更美观
# awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd
root           : Admin
bin            : Common User
daemon         : Common User
adm            : Common User
lp             : Common User
统计id号大于等于500的用户个数
# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
21

7.2 while

语法: while (condition){statement1; statment2; ...}

实例分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
显示字符串大于等于8的(每一个字符串都要做一下判断)
# awk -F: '{i=1;while (i<=NF) {if (length($i)>=8) {print $i}; i++ }}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/var/adm
/sbin/nologin
/var/spool/lpd
显示字符串大于等于4
# awk -F: '{i=1;while (i<=NF){if (length($i)>=4) {print $i}; i++}}' /etc/passwd
root
root
/root
/bin/bash
/bin
/sbin/nologin
daemon
daemon

7.3 do-while

语法: do {statement1, statement2, ...} while (condition)

1
2
3
4
5
6
显示字符串小于等于4的(注意使用do语句时,先执行的是条件)
# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd
root
x
0
bin

7.4 for

语法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}

例题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1、显示字符串大于等于4
# awk -F: '{for(i=1;i<=NF;i++) {if (length($i)>=4) {print $i}}}' /etc/passwd
root
root
/root
/bin/bash
2、显示字符串小于等于4
# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
root
x
0
bin
for循环还可以用来遍历数组元素:
语法: for (i in array) {statement1, statement2
例如:显示
# awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%-15s:%i\n",A,BASH[A]}}' /etc/passwd
/bin/sync      :1
/bin/bash      :20
/sbin/nologin  :31
/sbin/halt     :1
/etc/tcsh      :1
/sbin/shutdown :1

7.5 case

语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default:

statement1, ...}

7.6 break 和 continue

常用于循环或case语句中

7.7 next

提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:

1
2
3
4
5
6
7
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
bin 1
adm 3
sync 5
halt 7
news 9
operator 11

八、awk中使用数组

8.1 数组

array[index-expression]

index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。要遍历数组中的每一个元素,需要使用如下的特殊结构:

for (var in array) { statement1, ... }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
显示各个shell的个数和
# awk -F: '{shell[$NF]++}END{for(A in shell) {print A,shell[A]}}' /etc/passwd
 1
/bin/sync 1
/bin/bash 20
/sbin/nologin 31
/sbin/halt 1
/etc/tcsh 1
/sbin/shutdown 1
其中,var用于引用数组下标,而不是元素值;
统计tcp连接状态的个数($6也是最后一个字段,可以使用$NF)
# netstat -ant | awk '/^tcp/ {STATE[$NF]++} END {for(a in STATE) print a, STATE[a]}'
LISTEN 11
ESTABLISHED 2
每出现一次被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的
最后一个字段,此处用其值做为数组S的元素索引;
统计访问本地的IP及个数
# awk '{count[$1]++}END{for(ip in count) {printf "%-20s:%d\n",ip,count[ip]}}'
/var/log/httpd/access_log
192.168.10.1      1
172.16.50.5       10
用法与上一个例子相同,用于统计某日志文件中IP地的访问量

8.2 删除数组变量

从关系数组中删除数组索引需要使用delete命令。使用格式为:

delete  array[index]

九、awk的内置函数

split(string, array [, fieldsep [, seps ] ])

功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;

# netstat -ant | awk '/:80\>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50

length([string])

功能:返回string字符串中字符的个数;

substr(string, start [, length])

功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;

system(command)

功能:执行系统command并将结果返回至awk命令

systime()

功能:取系统当前时间

tolower(s)

功能:将s中的所有字母转为小写

toupper(s)

功能:将s中的所有字母转为大写

十、用户自定义函数

自定义函数使用function关键字。格式如下:

function F_NAME([variable])

{

statements

}

函数还可以使用return语句返回值,格式为“return value”。

原文地址:http://jilili.blog.51cto.com/6617089/1196748

转 shell awk 使用详解的更多相关文章

  1. shell编程之awk命令详解

    shell编程之awk命令详解 a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; out ...

  2. Shell学习(五)—— awk命令详解

    一.awk简介   awk是一个非常好用的数据处理工具,相对于sed常常作用于一整个行的处理,awk则比较倾向于一行当中分成数个[字段]处理,因此,awk相当适合处理小型的数据数据处理.awk是一种报 ...

  3. linux awk命令详解

    linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...

  4. shell字符串操作详解

    shell字符串操作详解的相关资料. 1.shell变量声明的判断  表达式 含义 ${var} 变量var的值, 与$var相同 ${var-DEFAULT} 如果var没有被声明, 那么就以$DE ...

  5. awk命令详解二

    awk命令详解 简单使用: awk :对于文件中一行行的独处来执行操作 . awk -F :'{print $1,$4}'   :使用‘:’来分割这一行,把这一行的第一第四个域打印出来 . 详细介绍: ...

  6. linux awk命令详解,使用system来内嵌系统命令, awk合并两列

    linux awk命令详解 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分 ...

  7. 3.awk数组详解及企业实战案例

    awk数组详解及企业实战案例 3.打印数组: [root@nfs-server test]# awk 'BEGIN{array[1]="zhurui";array[2]=" ...

  8. [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等

    本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...

  9. (转)awk数组详解及企业实战案例

    awk数组详解及企业实战案例 原文:http://www.cnblogs.com/hackerer/p/5365967.html#_label03.打印数组:1. [root@nfs-server t ...

随机推荐

  1. 【Python】回文

    首先判断一个字符串是否回文: def isPlalind(s): if len(s) == 1: return True else: return s[0] == s[-1] and isPlalin ...

  2. [Q]pdfFactory虚拟打印机的安装

    安装打图精灵过程中会提示是否安装pdfFactory虚拟打印机,建议选择安装. 若未安装,在安装打图精灵之后想安装pdfFactory,该软件可以在打图精灵应用程序文件夹下找到( 系统"开始 ...

  3. [Q]安装问题(找不到InstallUtilLib.dll)

    安装时提示 使用下面的方法解决(参考) 一.如果您的系统提示“没有找到Installutillib.Dll”或者“缺少Installutillib.Dll”等类似错误信息,请把Installutill ...

  4. 容易忘记的几个Linux命令

    #查看文件或者目录的属性ls -ld filenamels -ld directory #vi编辑器输入:.,$d #清除全部内容 #修改管理员.用户密码passwd user #("use ...

  5. C# 语言规范_版本5.0 (第11章 结构)

    1. 结构 结构与类的相似之处在于,它们都表示可以包含数据成员和函数成员的数据结构.但是,与类不同,结构是一种值类型,并且不需要堆分配.结构类型的变量直接包含了该结构的数据,而类类型的变量所包含的只是 ...

  6. Ubuntu 16.04安装和配置Sublime Text 3

    1.安装Sublime Text 3 首先添加sublime text 3的仓库: sudo add-apt-repository ppa:webupd8team/sublime-text-3 根据提 ...

  7. HTML4基础

                                                                            form 表单 首先,讨论“控件”(下面很多都是新控件, ...

  8. kubernetes port nodePort targetPort 理解

    port The port that the service is exposed on the service's cluster ip (virsual ip). Port is the serv ...

  9. laravel创建定时任务

    官方文档给出的教程已经很详细了,这里给出一些补充帮助大家理解. 英文文档:https://laravel.com/docs/5.2/scheduling 中文文档:https://laravel-ch ...

  10. DEV TdxLayoutGroup设置tab

    TdxLayoutGroup 属性的 LayoutDirection :ldvertical,ldtabbed(显示tab页),ldhorizontal