Linux文本处理必杀技之awk应用详解

AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/awk)

awk是一款强大的报告日志生成处理工具,不同于sed和grep,它的侧重点是如何把文本信息更好的展示出来,常用与统计和格式化输出。awk相当于微型的shell,有着自己一套语法结构,例如:循环结构,数组,条件判断,函数,内置变量等功能。处理对象一般纯文本文件或纯文本信息,同时它也能与正则表达式完全兼容使用。

awk应用详解:

awk基本语法结构:

awk [options] ‘/pattern/{action}‘ file1 file2 ...
#awk [可选参数] ‘模式{动作}‘    文件1 文件2 ...

awk [options] ‘script‘ file1 file2 ...
#awk [可选参数] ‘脚本‘  文件1 文件2 ...

---------------------------------------------------------------------------------

awk结果输出

print     item1,item2,...
#打印显示 项目1,项目2,...

结果输出显示应用详解

(1)各项目之间使用逗号分隔,而输出时则使用输出分隔符分隔。

(2)输出的各item(项目)可以是字符串、数值、当前记录的字段、变量或awk的表达式,数值会被隐式转换为字符串后输出。

(3)print后面item如果省略,相当于print $0,输出所有数据;若输出空白,则使用print ""。

示例如下:

使用print格式输出显示当前系统下所有用户名和用户使用的shell

# awk -F: ‘{print $1,$7}‘ /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync

使用print格式输出显示当前系统下所有用户的所有信息

# awk -F: ‘{print $0}‘ /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

使用print格式输出显示当前系统下所有用户的所有信息为空输出

# awk -F: ‘{print ""}‘ /etc/passwd

awk模式应用:

(1)Regexp: 格式为/pattern/,仅处理被/pattern/匹配到的行
(2)Expression: 表达式,其结果为非0或非空字符串时满足条件,仅处理满足条件的行
(3)Ranges: 行范围,此前地址定界,startline, endline,仅处理范围内的行
(4) BEGIN/END: 特殊模式,仅在awk命令的program运行之前(BEGIN)或运行之后(END)执行一次
(5)Empty:空模式,匹配任意行

awk的变量应用
内置变量

FS:Field Seperator, 输入时的字段分隔符;
RS:Record Seperator, 输出行分隔符;
OFS: Output Field Seperator, 输出时的字段分隔符;
ORS: Outpput Row Seperator, 输出时的行分隔符;

示例如下:

使用指定输入字段分隔符为":"显示/etc/passwd用户名和用户登录使用的shell。

# awk ‘BEGIN{FS=":"}/root/{print $1,$7}‘ /etc/passwd
root /bin/bash
operator /sbin/nologin

使用指定输入字段分隔符为":",输出字段分隔符为"#",显示/etc/passwd用户名和用户登录使用的shell。

# awk ‘BEGIN{FS=":";OFS="#"}/root/{print $1,$7}‘ /etc/passwd
root#/bin/bash
operator#/sbin/nologin

使用指定输入字段分隔符为":",输出字段分隔符为"#",输出时的行分隔符,显示/etc/passwd用户名和用户登录使用的shell。

# awk ‘BEGIN{FS=":";OFS="#";ORS="*"}/root/{print $1,$7}‘ /etc/passwd
root#/bin/bash*operator#/sbin/nologin*

--------------------------------------------------------------------------------------------------------

NR:Numbers of Record,行数;所有文件一并计数

显示所处理文件的行数(合并计数):

[[email protected] ~]# awk ‘{print NR,$0}‘ /etc/issue /etc/fstab 
1 CentOS release 6.5 (Final)
2 Kernel \r on an \m
3 
4 
5 #
6 # /etc/fstab
7 # Created by anaconda on Fri Mar 18 16:36:32 2016
8 #
9 # Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
10 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
11 #
12 /dev/mapper/vg0-root    /                       ext4    defaults        1 1
13 UUID=26e4890e-309c-4afb-842e-218614b31f49 /boot                   ext4    defaults        1 2
14 /dev/mapper/vg0-usr     /usr                    ext4    defaults        1 2
15 /dev/mapper/vg0-var     /var                    ext4    defaults        1 2
16 /dev/mapper/vg0-swap    swap                    swap    defaults        0 0
17 tmpfs                   /dev/shm                tmpfs   defaults        0 0
18 devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
19 sysfs                   /sys                    sysfs   defaults        0 0
20 proc                    /proc                   proc    defaults        0 0

--------------------------------------------------------------------------------------------------------

NF:Numbers of Field,字段数

显示所有处理文件的每行的字段数:

# awk ‘{print NF,$0}‘ /etc/issue /etc/fstab 
4 CentOS release 6.5 (Final)
5 Kernel \r on an \m
0 
0 
1 #
2 # /etc/fstab
10 # Created by anaconda on Fri Mar 18 16:36:32 2016
1 #
9 # Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
12 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
1 #
6 /dev/mapper/vg0-root    /                       ext4    defaults        1 1
6 UUID=26e4890e-309c-4afb-842e-218614b31f49 /boot                   ext4    defaults        1 2
6 /dev/mapper/vg0-usr     /usr                    ext4    defaults        1 2
6 /dev/mapper/vg0-var     /var                    ext4    defaults        1 2
6 /dev/mapper/vg0-swap    swap                    swap    defaults        0 0
6 tmpfs                   /dev/shm                tmpfs   defaults        0 0
6 devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
6 sysfs                   /sys                    sysfs   defaults        0 0
6 proc                    /proc                   proc    defaults        0 0

--------------------------------------------------------------------------------------------------------

FNR:行数;多文件处理时分别对文件计数。

显示所处理文件的行数(分别计数):

# awk ‘{print FNR,$0}‘ /etc/issue /etc/fstab 
1 CentOS release 6.5 (Final)
2 Kernel \r on an \m
3 
1 
2 #
3 # /etc/fstab
4 # Created by anaconda on Fri Mar 18 16:36:32 2016
5 #
6 # Accessible filesystems, by reference, are maintained under ‘/dev/disk‘
7 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
8 #
9 /dev/mapper/vg0-root    /                       ext4    defaults        1 1
10 UUID=26e4890e-309c-4afb-842e-218614b31f49 /boot                   ext4    defaults        1 2
11 /dev/mapper/vg0-usr     /usr                    ext4    defaults        1 2
12 /dev/mapper/vg0-var     /var                    ext4    defaults        1 2
13 /dev/mapper/vg0-swap    swap                    swap    defaults        0 0
14 tmpfs                   /dev/shm                tmpfs   defaults        0 0
15 devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
16 sysfs                   /sys                    sysfs   defaults        0 0
17 proc                    /proc                   proc    defaults        0 0

--------------------------------------------------------------------------------------------------------

ARGV: 数组,保存命令行本身这个字符串,如awk ‘{print $0}‘ a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;ARGV[2]保存b.txt
ARGC: awk命令的参数的个数;
FILENAME: awk命令所处理的文件的名称;
ENVIRON:当前shell环境变量及其值的关联数组;

数组示例如下:

显示当前awk数组参数保存的信息

# awk ‘{print ARGV[0], ARGV[1],ARGV[2]}‘ open.sh samlee.sh 
awk open.sh samlee.sh

显示当前awk参数的个数

# awk ‘{print ARGC}‘ open.sh samlee.sh 
3

显示当前awk正在处理的文件名称

# awk ‘{print FILENAME}‘ open.sh samlee.sh 
open.sh
samlee.sh

用户自定义变量

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

自定义变量声明:

-v var_name=VALUE    #变量名区分字符大小写

(1)在脚本中赋值变量
在gawk中给变量赋值使用赋值语句进行,

例如:
awk ‘BEGIN{var="variable testing";print var}‘

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

例如,上述的例子还可以改写为:
awk -v var="variable testing" ‘BEGIN{print var}‘

示例如下:

# awk ‘BEGIN{S="samlee";print S}‘
samlee
# awk -v S="samlee" ‘BEGIN{print S}‘
samlee

awk-printf命令的应用:

printf命令的使用格式:

printf format, item1, item2, ...

要点:
1、其与print命令的最大不同是,printf需要指定format;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符;\n

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

%c: 显示字符的ASCII码;
%d, %i:十进制整数;
%e, %E:科学计数法显示数值;
%f: 显示浮点数;
%g, %G: 以科学计数法的格式或浮点数的格式显示数值;
%s: 显示字符串;
%u: 无符号整数;
%%: 显示%自身;

修饰符:

N: 显示宽度;
-: 左对齐;
+:显示数值符号;

示例如下:

使用printf输出显示自定义变量值的ASCII码

# awk ‘BEGIN{str=70;printf "%c\n",str}‘
F

使用printf输出显示自定义变量值保留2位小数

# awk ‘BEGIN{str=4.131254;printf "%.2f\n",str}‘
4.13

使用printf输出显示/etc/passwd用户名和UID按列指定位置显示

# awk -F: ‘{printf "%+10s %-5d\n",$1,$3}‘ /etc/passwd
      root 0    
       bin 1    
    daemon 2    
       adm 3    
        lp 4    
      sync 5    
  shutdown 6    
      halt 7    
      mail 8    
      uucp 10   
  operator 11   
     games 12   
    gopher 13 
# awk -F: ‘{printf "%+10s %i\n",$1,$3}‘ /etc/passwd
      root 0    
       bin 1    
    daemon 2    
       adm 3    
        lp 4    
      sync 5    
  shutdown 6    
      halt 7    
      mail 8    
      uucp 10   
  operator 11   
     games 12   
    gopher 13

awk输出重定向应用

print items > output-file     #保存到某文件
print items >> output-file    #追加到某文件
print items | command         #使用管道交给某些命令处理
 
特殊文件描述符:
    /dev/stdin: 标准输入
    /dev/stdout: 标准输出
    /dev/stderr: 错误输出
    /dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;

示例如下:

将错误信息输出

# awk -F: ‘{printf "%-15s %i\n",$1,$3 > "/dev/stderr" }‘ /etc/passwd

将信息输出指定文件中保存

# awk -F" " ‘{printf "%-10s %d\n",$1,$3 > "/tmp/outinfo"}‘ /etc/passwd
# cat /tmp/outinfo 
root:x:0:0:root:/root:/bin/bash 0
bin:x:1:1:bin:/bin:/sbin/nologin 0

awk操作符应用

算术操作符:
-x: 负值
+x: 转换为数值;
x^y: 
x**y: 次方
x*y: 乘法
x/y:除法
x+y:
x-y:
x%y:

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

赋值操作符:
=
+=
-=
*=
/=
%=
^=
**=
++
--
需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;

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

比较操作符:
x < y    True if x is less than y. 
x <= y    True if x is less than or equal to y. 
x > y    True if x is greater than y. 
x >= y    True if x is greater than or equal to y. 
x == y    True if x is equal to y. 
x != y    True if x is not equal to y. 
x ~ y    模式匹配,左边的字符串能够被右边的模式所匹配为真,否则为假
x !~ y    不匹配为真,匹配为假
subscript in array      True if the array array has an element with the subscript subscript.

表达式间的逻辑关系符:
&&:与
||:或

条件表达式:
selector?if-true-exp:if-false-exp

if selector; then
  if-true-exp
else
  if-false-exp
fi

a=3
b=4
a>b?a is max:b ia max

函数调用:
function_name(para1,para2)

示例如下:

判断UID是否大于等于500,如果为真就显示为普通用户,如果为假就显示为系统或管理用户。

# awk -F: ‘{$3>=500?utype="common user":utype="admin or system user";print $1,"is" utype}‘ /etc/passwd
root isadmin or system user
bin isadmin or system user
daemon isadmin or system user
adm isadmin or system user
lp isadmin or system user

常用的action
Expressions:表达式 赋值等
Control statements:条件语句,控制语句if while…
Compound statements:组合语句
input statements:输入语句
output statements:输出语句

条件控制语句:

if-else格式:

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

示例如下:

输出显示uid>=500的用户显示为普通用户,否则显示为系统管理用户。

# awk -F: ‘{if ($3>=500) {print $1,"is a common user"} else {print $1,"is an admin or system user"}}‘ /etc/passwd
root is an admin or system user
bin is an admin or system user
daemon is an admin or system user
adm is an admin or system user
lp is an admin or system user

输出显示uid=0的用户显示为系统管理员用户,否则显示为普通用户。

# awk ‘{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}‘ /etc/passwd

输出显示用户为root标识为系统管理员,否则显示普通管理用户。

# awk -F: ‘{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}‘ /etc/passwd
# awk -F: ‘{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}‘ /etc/passwd

输出显示uid>=500的用户数量

# awk -F: -v sum=0 ‘{if ($3>=500) sum++}END{print sum}‘ /etc/passwd

显示文件中字段数大于等于8的行

# awk ‘{if (NF>=8) {print}}‘ /etc/inittab

输出显示uid>=500的用户

# awk -F : ‘{if ($3>=500) {print $0}}‘ /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
888:x:500:500::/home/888:/bin/bash
hadoop:x:501:501::/home/hadoop:/bin/bash

while循环控制

while格式如下:

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

示例如下:

显示所有用户的用户名、口令、uid字段

awk -F: ‘{i=1;while (i<=3) {print $i;i++}}‘ /etc/passwd

只输出每行大于4的字段

awk -F: ‘{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}‘ /etc/passwd

只显示文件的奇数行

# awk ‘{i=1; while (i<=NF){printf "%s ",$i;i+=2};print " "}‘ /etc/inittab

do-while循环

do-while 至少执行一次循环体,不管条件满足与否

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

显示所有用户的用户名、口令、uid字段

# awk -F: ‘{i=1;do {print $i;i++}while(i<=3)}‘ /etc/passwd

输出1到100之和

# awk ‘BEGIN{sum=0;i=0;do{sum+=i;i++;}while(i<=100) print sum;}‘
5050

for循环控制

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

显示所有用户的用户名、口令、uid字段

# awk -F: ‘{for(i=1;i<=3;i++) print $i}‘ /etc/passwd

只输出每行大于4的字段

# awk -F: ‘{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}‘ /etc/passwd

for循环还可以用来遍历数组元素

语法: for (i in array) {statement1, statement2, ...}

汇总各个shell使用的用户数量

awk -F: ‘$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}‘ /etc/passwd

case

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

break 和 continue
常用于循环或case语句中

next
提前结束对本行文本的处理,并接着处理下一行;

显示其ID号为奇数的用户

# awk -F: ‘{if($3%2==0) next;print $1,$3}‘ /etc/passwd

输出奇数行的用户

# awk -F: ‘{if(NR%2==0) next;print NR,$1,$3}‘ /etc/passwd

 

awk中使用数组
 数组声明格式:

array[index-expression]

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

要遍历数组中的每一个元素,需要使用如下的特殊结构:

for (var in array) { statement1, ... }   #其中,var用于引用数组下标,而不是元素值;

示例如下:

统计每一种网络连接状态出现的次数

# netstat -tan|awk ‘/^tcp/{++state[$NF]}END{for (s in state) {print s,state[s]}}‘
ESTABLISHED 5
LISTEN 20
每出现一被/^tcp/模式匹配到的行,数组state[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组state的元素索引;

统计web服务访问日志中的ip访问量

# awk ‘{counts[$1]++}; END {for(url in counts) print url,counts[url]}‘ /var/log/httpd/access_log
172.16.0.1 209
#用法与上一个例子相同,用于统计某日志文件中IP地的访问量

删除数组变量
从关系数组中删除数组索引需要使用delete命令。

使用格式为:

delete  array[index]

awk的内置函数

split(string,array[,fieldsep[,seps]])
功能:将string表示的字符串以fieldsep为分隔符进行切片,并切片后的结果保存至array为名的数组中;数组下标从1开始
此函数有返回值,返回值为切片后的元素的个数

统计连接请求的IP地址

# netstat -tn|awk ‘/^tcp/{lens=split($5,client,":");ip[client[lens-1]]++}END{for(i in ip) print i,ip[i]}‘
172.16.0.1 2
127.0.0.1 2
205.177.69.146 2
length([string])
功能:返回string字符串中字符的个数;

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

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

systime()
功能:取系统当前时间

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

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

以上Linux文本处理必杀技之awk应用详解所有内容。

时间: 2024-10-12 21:38:16

Linux文本处理必杀技之awk应用详解的相关文章

linux文本处理三剑客之grep命令详解

Linux文本处理三剑客之grep grep:文本过滤(模式:pattern)工具 grep, egrep, fgrep(不支持正则表达式搜索) sed:stream editor,文本编辑工具 awk:Linux上的实现gawk,文本报告生成器 grep grep: Global search REgularexpression and Print out the line 作用:文本搜索工具,根据用户指定的"模式"对目标文本逐行进行匹配检查:打印匹配到的行 模式:由正则表达式字符及

Linux awk 命令详解

简介linux awk命令详解 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的

linux awk命令详解(都是常用命令)

原文:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它

awk命令详解二

awk命令详解 简单使用: awk :对于文件中一行行的独处来执行操作 . awk -F :'{print $1,$4}'   :使用‘:’来分割这一行,把这一行的第一第四个域打印出来 . 详细介绍: AWK命令介绍 awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作,完整的awk脚本通常用来格式化文本文件中的信息 1.   调用awk: 第一种命令行方式,如: awk [-Field-separator] 'commands' input

Linux系统根文件以及命名规则详解

一.Linux系统根文件详解 Linux的重要哲学思想其实就是:将程序的配置文件保存为纯文本格式. 1./boot:系统启动文件,如:内核文件,iniyrd以及gurb(bootloarder) 2./dev:目录下为设备文件,设备文件又分为块设备和字符设备: 块设备:按数据块随机访问,没有顺序. 字符设备:线性访问,按字符为单位进行. 注:其中背景为黑色,字体为***的文件,为特殊文件,"1,   0"分别为文件的主设备号和次设备号 [[email protected] ~]# ls

文本处理工具之一grep命令详解

grep(Globel Search Regular Expression and Printing out the line)全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,是一个对行进行操作的搜索工作,它能使用正则表达式搜索文本,并把匹配的行打印出来.Unix的grep家族包括grep.egrep和fgrep. egrep表示扩展的grep,相比grep支持更多的元字符,"grep -E"相当于egrep.fgrep是fast grep,不支持元字符,但是搜索速度更快.

awk 命令详解

awk 用法(使用入门) [转]linux awk命令详解 awk命令

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

awk数组详解及企业实战案例 原文:http://www.cnblogs.com/hackerer/p/5365967.html#_label03.打印数组:1. [[email protected] test]# awk 'BEGIN{array[1]="zhurui";array[2]="zhuzhu";for(key in array) print key,array[key]}'2. 1 zhurui3. 2 zhuzhu4. [[email protect

1.12-linux三剑客之awk用法详解

1.12 linux三剑客之awk用法详解 内容: 1. awk执行过程 2. awk命令格式 3. awk用法 4. awk数组 第1章 awk执行过程 一直读取到文件的最后一行 第2章 awk '找谁{干啥}' '模式{动作}' 模式 pattern   动作  action 第3章 awk中什么可以作为模式 正则表达式 比较表达式    NR>10 范围模式 特殊模式BEGIN{}和END{} awk支持正则中的特殊符号 3.1 正则表达式 测试文件/server/files/reg.tx