AWK

作者: 楠有枝 | 来源:发表于2019-06-30 20:25 被阅读0次

awk简介

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。
awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。gawk是awk的GNU版本,它提供了Bell实验室和GNU的一些扩展。

awk的两种形式语法格式

awk [options] 'commands' filenames
awk [options] -f awk-script-file filenames

=options:

-F   定义输入字段分隔符,默认的分隔符是空格或制表符(tab)

=command:

BEGIN{}       {}               END{}
行处理前      行处理       行处理后
# awk 'BEGIN{print 1/2} {print "ok"} END{print "-----------"}' /etc/hosts
0.5
ok
ok
ok

-----------
BEGIN{}     通常用于定义一些变量,例如BEGIN{FS=":";OFS="---"}

=awk命令格式:

awk 'pattern' filename              示例:awk -F: '/root/' /etc/passwd     
awk '{action}' filename             示例:awk -F: '{print $1}' /etc/passwd         
awk 'pattern {action}' filename     示例:awk -F: '/root/{print $1,$3}' /etc/passwd    

awk工作原理

 awk -F: '{print $1,$3}' /etc/passwd
(1)awk使用一行作为输入,并将这一行赋给内部变量$0,每一行也可称为一个记录,以换行符结束

(2)然后,行被:(默认为空格或制表符)分解成字段(或域),每个字段存储在已编号的变量中,从$1开始,
最多达100个字段

(3)awk如何知道用空格来分隔字段的呢? 因为有一个内部变量FS来确定字段分隔符。初始时,FS赋为空格

(4)awk打印字段时,将以设置的方法使用print函数打印,awk在打印的字段间加上空格,因为$1,$3之间
有一个逗号。逗号比较特殊,它映射为另一个内部变量,称为输出字段分隔符OFS,OFS默认为空格

(5)awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔
成字段并进行处理。该过程将持续到所有行处理完毕
记录与字段相关内部变量:man awk
$0:     awk变量$0保存当前记录的内容                                # awk -F: '{print $0}' /etc/passwd                  显示文件本身了
NR:     The total number of input records seen so far.      # awk -F: '{print NR, $0}' /etc/passwd /etc/hosts     显示行号了
FNR:   The input record number in the current input file    # awk -F: '{print FNR, $0}' /etc/passwd /etc/hosts
NF:     保存记录的字段数,$1,$2...$100                           # awk -F: '{print $0,NF}' /etc/passwd    --NF  以: 为分隔符 显示 共有几行

在awk里,NR和FNR的含义相近,唯一的区别就是作用范围,NR是所有读取的行信息计数,而FNR是正在读取文件的行信息技术,FNR在文件切时会从0[重新开始]

格式化输出:

print函数
# date |awk '{print "Month: " $2 "\nYear: " $NF}'
# awk -F: '{print "username is: " $1 "\t uid is: " $3}' /etc/passwd
# awk -F: '{print "\tusername and uid: " $1,$3 "!"}' /etc/passwd

printf函数
# awk -F: '{printf "%-15s %-10s %-15s\n", $1,$2,$3}'  /etc/passwd
# awk -F: '{printf "|%-15s| %-10s| %-15s|\n", $1,$2,$3}' /etc/passwd

%s 字符类型
%d 数值类型
%f 浮点类型
占15字符
- 表示左对齐,默认是右对齐
printf默认不会在行尾自动换行,加\n

awk模式和动作

任何awk语句都由模式和动作组成。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。
如果省略模式部分,动作将时刻保持执行状态。模式可以是任何条件语句或复合语句或正则表达式。模式包括两
个特殊字段 BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之
后文本浏览动作依据输入文本开始执行。END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态。

模式可以是:
==正则表达式:
匹配记录(整行):

awk '/^alice/' /etc/passwd

awk '$0 ~ /^alice/' /etc/passwd

awk '!/alice/' passwd

awk '$0 !~ /^alice/' /etc/passwd

匹配字段:匹配操作符(~ !~)

awk -F: '$1 ~ /^alice/' /etc/passwd

awk -F: 'NF !~ /bash/' /etc/passwd

==比较表达式:

比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。比较表达式使用关系运算符,
用于比较数字与字符串。

关系运算符
运算符                       含义                        示例
<                          小于                          x<y
<=                        小于或等于                      x<=y
==                         等于                          x==y
!=                        不等于                         x!=y
>=                        大于等于                       x>=y
>                           大于                          x>y

awk -F: '$3 == 0' /etc/passwd

awk -F: '$3 < 10' /etc/passwd

awk -F: '$NF == "/bin/bash"' /etc/passwd

awk -F: '$1 == "alice"' /etc/passwd

awk -F: '$1 ~ /alic/ ' /etc/passwd

awk -F: '$1 !~ /alic/ ' /etc/passwd

df -P | grep '/' |awk '$4 > 25000'

==条件表达式:

awk -F: '3>300 {print0}' /etc/passwd

awk -F: '{ if(3>300) print0 }' /etc/passwd

awk -F: '{ if(3>300) {print0} }' /etc/passwd

awk -F: '{ if(3>300) {print3} else{print $1} }' /etc/passwd

==算术运算:

+ - * / %(模) ^(幂2^3)

可以在模式中执行计算,awk都将按浮点数方式执行算术运算
# awk -F: '$3 * 10 > 500' /etc/passwd
# awk -F: '{ if($3*10>500){print $0} }' /etc/passwd

==逻辑操作符和复合模式

&&     逻辑与     a&&b
||          逻辑或     a||b
!           逻辑非     !a

awk -F: '1~/root/ &&3<=15' /etc/passwd

awk -F: '1~/root/ ||3<=15' /etc/passwd

awk -F: '!(1~/root/ ||3<=15)' /etc/passwd

==范围模式

awk '/Tom/,/Suzanne/' filename

awk示例:

awk '/west/' datafile

awk '/^north/' datafile

awk '$3 ~ /^north/' datafile

awk '/^(no|so)/' datafile

awk '{print 3,2}' datafile

awk '{print 32}' datafile

awk '{print $0}' datafile

awk '{print "Number of fields: "NF}' datafile

awk '/northeast/{print 3,2}' datafile

awk '/E/' datafile

awk '/^[ns]/{print $1}' datafile

awk '$5 ~ /.[7-9]+/' datafile

awk '2 !~ /E/{print1,$2}' datafile

awk '3 ~ /^Joel/{print3 " is a nice boy."}' datafile

awk '8 ~ /[0-9][0-9]/{print $8}' datafile

awk '4 ~ /Chin/{print "The price is "8 "."}' datafile

awk '/Tj/{print $0}' datafile

awk '{print $1}' /etc/passwd

awk -F: '{print $1}' /etc/passwd

awk '{print "Number of fields: "NF}' /etc/passwd

awk -F: '{print "Number of fields: "NF}' /etc/passwd

awk -F"[ :]" '{print NF}' /etc/passwd

awk -F"[ :]+" '{print NF}' /etc/passwd

awk '$7 == 5' datafile

awk '2 == "CT" {print1, $2}' datafile

awk '$7 != 5' datafile

lab3:
[root@nan ~]# cat b.txt
yang sheng:is a::good boy!
[root@nan ~]# awk '{print NF}' b.txt
4
[root@nan ~]# awk -F: '{print NF}' b.txt
4
[root@nan ~]# awk -F"[ :]" '{print NF}' b.txt
7
[root@nan ~]# awk -F"[ :]+" '{print NF}' b.txt
6

# awk '$7 < 5 {print $4, $7}' datafile            {if($7<5){print $4,$7}}
# awk '$6 > .9 {print $1,$6}' datafile
# awk '$8 <= 17 {print $8}' datafile
# awk '$8 >= 17 {print $8}' datafile
# awk '$8 > 10 && $8 < 17' datafile

# awk '$2 == "NW" || $1 ~ /south/ {print $1, $2}' datafile
# awk '!($8 == 13){print $8}' datafile                    #$8 != 13
# awk '/southem/{print $5 + 10}' datafile
# awk '/southem/{print $8 + 10}' datafile
# awk '/southem/{print $5 + 10.56}' datafile

# awk '/southem/{print $8 - 10}' datafile
# awk '/southem/{print $8 / 2 }' datafile
# awk '/southem/{print $8 / 3 }' datafile
# awk '/southem/{print $8 * 2 }' datafile
# awk '/southem/{print $8 % 2 }' datafile

># awk '$3 ~ /^Suan/ {print "Percentage: "$6 + .2   " Volume: " $8}' datafile
# awk '/^western/,/^eastern/' datafile
# awk '{print ($7 > 4 ? "high "$7 : "low "$7)}' datafile            //三目运算符 a?b:c 条件?结果1:结果2
# awk '$3 == "Chris" {$3 = "Christian"; print $0}' datafile     //赋值运算符
# awk '/Derek/ {$8+=12; print $8}' datafile                         //$8 += 12等价于$8 = $8 + 12
# awk '{$7%=3; print $7}' datafile                                      //$7 %= 3等价于$7 = $7 % 3 

awk脚本编程
==条件判断

if语句:
格式
{if(表达式){语句;语句;...}}

awk -F: '{if($3==0) {print $1 " is administrator."}}' /etc/passwd
awk -F: '{if($3>0 && $3<1000){count++;}}  END{print count}' /etc/passwd   //统计系统用户数


if...else语句:
格式
{if(表达式){语句;语句;...}else{语句;语句;...}}

awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd
awk -F: '{if($3==0) {count++} else{i++} }' /etc/passwd
awk -F: '{if($3==0){count++} else{i++}} END{print "管理员个数: "count ; print "系统用户数: "i}' /etc/passwd


if...else if...else语句:
格式
{if(表达式1){语句;语句;...}else if(表达式2){语句;语句;...}else if(表达式3){语句;语句;...}else{语句;语句;...}}

awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i; print k; print j}' /etc/passwd
awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理员个数: "i; print "普通用个数: "k; print "系统用户: "j}' /etc/passwd 

==循环
while:
[root@nan ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++}  }'
[root@nan ~]# awk -F: '/^root/{i=1; while(i<=7){print $i; i++}}' passwd
[root@nan ~]# awk  '{i=1; while(i<=NF){print $i; i++}}' /etc/hosts
[root@nan ~]# awk -F: '{i=1; while(i<=10) {print $0;  i++}}' /etc/passwd       //将每行打印10次
[root@nan ~]# cat b.txt 
111 222
333 444 555
666 777 888 999
[root@nan ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt                       //分别打印每行的每列
111
222
333
444
555
666
777
888
999

for:
[root@nan ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }'                              //C风格for
1
2
3
4
5
[root@nan ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' /etc/passwd        //将每行打印10次
[root@nan~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' passwd               //分别打印每行的每列
root
x
0
0
root
/root
/bin/bash
bin
x
1
1
bin
/bin
/sbin/nologin

五星重点 !!!!!!!!!!!!!!!!!!!!!!

awk -F ":" '{print $1}'  XXX        -F ":"  以:分割      正常是按空格或者tab分割

。

相关文章

  • 18-文本处理三剑客之awk

    本章内容 ◆ awk介绍◆ awk基本用法◆ awk变量◆ awk格式化◆ awk操作符◆ awk条件判断◆ aw...

  • 2017 09-04 AWK

    本章主要学习内容awk介绍 awk基本用法 awk变量 awk格式化 awk操作符 awk条件判断 a...

  • 【技术案例】跟老男孩学运维-awk项目案例

    一个awk数组应用案例 [TOC] 0.技术点: awk awk数组 awk判断 awk数组赋值 awk函数spl...

  • awk

    awk:报告生成器,格式化文本输出 内容: awk介绍 awk基本用法 awk变量 awk格式化 awk操作符 a...

  • awk

    Linux System Environment awk功能 awk格式 awk 参数 一、awk截取列 二、显示...

  • 笔记-awk

    1.Awk基础介绍 2.awk语法格式 2.Awk工作原理 3.Awk内部变量 4.Awk格式输出 5.Awk模式...

  • awk用法详解

    awk 用法 awk ' pattern {action} ' 1、awk '/101/' file ...

  • Day64-shell编程_正则表达式_awk

    1.Awk基础介绍 2.Awk工作原理 3.Awk内部变量 4.Awk格式输出 5.Awk模式匹配 5.1符号 ...

  • linux-awk

    linux-awk awk基本结构 awk ‘BEGIN{ print “start”} pattern { co...

  • awk小说

    awk awk脚本的结构基本如下: awk ' BEGIN{ print "start" } patern { c...

网友评论

    本文标题:AWK

    本文链接:https://www.haomeiwen.com/subject/yazbcctx.html