您的位置:时时app平台注册网站 > 时时app平台注册网站 > awk

awk

2019-11-01 21:15

向脚本传递参数

var=root
awk –F: -v a=$var ‘$1==a {print}’ /etc/passwd

求阶乘
5!=5*4*3*2*1

影响控制流
break 退出循环
continue 终止当前的循环,并从循环的顶部开始一个新的循环
影响主输入循环
next 读入下一行,并返回脚本的顶部
exit 使主输入循环退出并将控制转移到END

 

 

ll |awk 'BEGIN{printf("%-5st%sn"),"name","size";FS=" ";}/^-/{printf ("%-5st%sn",$NF,$5);i =$5}END{printf("%-5st%sn"),"total",i}'

ll |awk 'BEGIN{printf("%-5st%sn"),"name","size";print "============";FS=" ";}/^-/{printf ("%-5st%sn",$NF,$5);i =$5}END{print "=============";printf("%-5st%sn"),"total",i}'

 

 

本章主要学习内容

  • awk介绍 
  • awk基本用法 
  • awk变量 
  • awk格式化 
  • awk操作符 
  • awk条件判断 
  • awk循环 
  • awk数组 
  • awk函数 
  • 调用系统命令

 

= i =j i=i j

*=
/=
%=
^=

二.awk工作原理

  • 第一步:执行BEGIN{action;… }语句块中的语句 
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,从第一行到最后一行重复这 个过程,直到文件全部被读取完毕。
  • 第三步:当读至输入流末尾时,执行END{action;…}语句块 
  • BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个 可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中 
  • END语句块在awk从输入流中读取完所有的行之后即被执行,比如 打印所有行的分析结果这类信息汇总都是在END语句块中完成,它 也是一个可选语句块 
  • pattern语句块中的通用命令是最重要的部分,也是可选的。如果 没有提供pattern语句块,则默认执行{ print },即打印每一个读取 到的行,awk读取的每一行都会执行该语句块
  • print格式:print item1, item2, ... 
    要点:
    (1) 逗号分隔符
    (2) 输出的各item可以字符串,也可以是数值;当前记录的字段、 变量或awk的表达式
    (3) 如省略item,相当于print $0

示例:

(1)awk '{print "welcome to magedu"}'

图片 1

image.png

(2) awk -F: '{print $1,$3}' /etc/passwd——默认以空格为分隔符

图片 2

image.png


(3)awk -F: '{print $1":"$3}' /etc/passwd——指定以“:”为分隔符

图片 3

image.png

(4) awk -F: '{print "magedu"}' /etc/passwd——在/etc/passwd的每一行都打印"magedu"

图片 4

image.png


(5)awk -F: '{print}' /etc/fstab——不写$1.....$n代表默认打印$0

图片 5

image.png


(6)awk -F: '{print $1}'

图片 6

image.png

awk -F":" '$1!="mysql"{print $3}' /etc/passwd                 //不等于

awk NR NF

NR (number of row)表示行

NF (number of field) 表示列(默认值为最后一列)

先来看一个实例:

获取剩余内存空间大小

[root@rhel6 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          3828        791       3037          0        110        494
-/  buffers/cache:        186       3642
Swap:         5999          0       5999
[root@rhel6 ~]# free -m | awk 'NR==3 {print $NF}'
3642

NF-5 == -6也就是倒数第四列

[root@rhel6 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          3828        791       3037          0        111        494
-/  buffers/cache:        186       3642
Swap:         5999          0       5999
[root@rhel6 ~]# free -m | awk 'NR==2 {print $(NF-5)}'
3828

三.awk变量

  • 变量:内置和自定义变量 
  • FS:输入字段分隔符,默认为空白字符
    awk -v FS=':' '{print $1,FS,$3}’ /etc/passwd
    例:
    fs=":" ; awk -v FS=$fs '{print $1,FS,$3}' /etc/passwd

    图片 7

    image.png

  • OFS:输出字段分隔符,默认为空白字符

    fs=":"; awk -v FS=$fs -v OFS=" " '{print$1,$3}' /etc/passwd

    图片 8

    image.png


    RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效 

    例子:

    图片 9

    image.png


    ORS:输出记录分隔符,输出时用指定符号代替换行符
    例子:awk -v RS=";" -v ORS="####" '{print $1,$3}' aaa.txt

    图片 10

    image.png


    NF:字段数量

    awk -F: '{print NF}' /etc/passwd

    图片 11

    image.png


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

    图片 12

    image.png


    NR:行号
    awk -F: '{print NR}' /etc/passwd

    图片 13

    image.png


    给/etc/fstab文件打印行号
    awk '{print NR, $0}' /etc/fstab

    图片 14

    image.png


    FNR:各文件分别计数,行号 ——效果就是如果同时读取多个文件时,可以分别进行计数打印行号,如果用NR则会将多个文件累加打印
    例:
    awk '{print NR}' /etc/fstab /etc/inittab

    图片 15

    image.png

    使用FNR则会解决该问题
    awk '{print FNR}' /etc/fstab /etc/inittab

    图片 16

    image.png


    FILENAME:当前文件名
    awk '{print FILENAME,NR,$0}' /etc/fstab

    图片 17

    image.png


    ARGC:命令行参数的个数
    awk '{print ARGC}’ /etc/fstab /etc/inittab
    awk ‘BEGIN {print ARGC}’ /etc/fstab /etc/inittab

    图片 18

    image.png


    ARGV:数组,保存的是命令行所给定的各参数
    awk ‘BEGIN {print ARGV[0]}’ /etc/fstab /etc/inittab

    图片 19

    image.png


    awk ‘BEGIN {print ARGV[1]}’ /etc/fstab /etc/inittab——代表第二参数,为/etc/fstab

  • awk变量
    自定义变量(区分字符大小写)
    (1) -v var=value
    (2) 在program中直接定义 
    示例:
    awk -v name="zhang" '{print name }' /etc/fstab

    图片 20

    image.png

    awk -v name="zhang" 'BEGIN{print name, "is ceo" }

    图片 21

    image.png


    也可以直接在{}里面定义
    awk '{sex=male;age=18;print sex,age}' aaa.txt

    图片 22

    image.png


    注意:{print sex ,age ;age=18},打印出来的效果是第一行不打印年龄

    图片 23

    image.png


    也支持调用文件来实现
    vim aaa.txt
    {sex="male";age=18;print $1,male,age}

    awk -F: -f aaa.txt /etc/passwd

    图片 24

    image.png

规律是先赋值后定义,否则会出现一些错误

awk -F: '/mysql/{print $3-$4}' /etc/passwd                             //减法

表达式:

常量:数字和字符串型
字符串型在表达式中必须用引号括起来
字符串中可以使用转义序列,常用的转义序列有:
n 换行 t 水平制表符 r 回车

赋值操作符:
i =i 1
-- i--=i-1

一.awk介绍

(一)awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出 
有多种版本:New awk(nawk),GNU awk( gawk) 
gawk:模式扫描和处理语言 
基本用法: awk [options] ‘program’ var=value file…
awk [options] -f programfile var=value file…
awk [options] 'BEGIN{ action;… } pattern{ action;… } END{ action;… }' file ...
awk 程序通常由:BEGIN语句块、能够使用模式匹配的通用语句块 、END语句块,共3部分组成 program通常是被单引号或双引号中
例: awk '{print 25}' /etc/passwd

图片 25

image.png


引入BEGIN,END
例:awk 'BEGIN{print 35}' /etc/passwd

图片 26

image.png


awk 'END{print 35}' /etc/passwd

选项:
-F 指明输入时用到的字段分隔符
-v var=value: 自定义变量
(二)基本格式:awk [options] 'program' file… 
program:pattern{action statements;..}
pattern和action:
• pattern部分决定动作语句何时触发及触发事件
BEGIN,END
• action statements对数据进行处理,放在{}内指明 print, printf  分割符、域和记录
• awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称 为域标识。$0为所有域,注意:和shell中变量$符含义不同
• 文件的每一行称为记录 • 省略action,则默认执行 print $0 的操作

ORS         输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕

关系操作符:

< 小于Less than
> 大于Greater than
<= 小于等于Less than or equal to
>= 大于等于Greater than or equal to
== 等于Equal to
NF==5 NF(每个输入记录的字段数)的值和5相比较,如果结果为真,那么就进行相应的处理,否则不进行处理。
!= 不等于Not equal to
~ 匹配Matches
$5~/MA/ {print $1 “,”$6}
!~ 不匹配Does not match
注意:关系操作符==和赋值操作符=是不同的

五.操作符

(一) 算术操作符:
x y, x-y, x*y, x/y, x^y, x%y
例:
awk 'BEGIN{print 2^3}'
awk 'BEGIN{print 2 3}'
awk 'BEGIN{print 2^3}'
-x: 转换为负数
x: 转换为数值 
(二)字符串操作符:没有符号的操作符,字符串连接 
赋值操作符: =, =, -=, *=, /=, %=, ^= , -
awk 'BEGIN{print i }'
awk 'BEGIN{print i}'

图片 27

image.png


awk -v n=100 'BEGIN{sum=100;print sum =n;pirnt sum }'

图片 28


比较操作符: ==, !=, >, >=, <, <= 
模式匹配符:~:左边是否和右边匹配包含
!~:是否不匹配
awk –F: '$0 ~ /root/{print $1}‘ /etc/passwd
awk -F : '$0 !~ /root/{print $1}' /etc/passwd

图片 29

image.png


awk '$0~"^root" ' /etc/passwd——root 后不写{print} 默认打印$0
也可以写成 awk '$0~/^root/{print $0}' /etc/passwd
awk –F: '$3==0' /etc/passwd

图片 30

image.png


(三)逻辑操作符:
与&&,或||,非! 
示例:
awk -F: ' $3>=100&&$3<=1000 {print $0}' /etc/passwd——$3是否大于100且小于1000,满足条件打印结果

图片 31

image.png


awk -F: '$3>=1000|| $3<=100{print $3}' /etc/passwd

图片 32

image.png


awk -F: '!($3==0){print $3}' /etc/passwd
(四)函数调用: function_name(argu1, argu2, ...) 
条件表达式(三目表达式): selector?if-true-expression:if-false-expression
示例:
awlk -F: '{$3>=1000?usertype="commonuser":usertype="sysuser or sysadmin";printf "%-30s %-10sn" ,$1,usertype}' /etc/passwd

图片 33

image.png


解释:首先判断$3是否大于1000,如果大于一千则显示用户类型为'commonuser',当小于一千时,则显示用户类型为'sysuser or sysadmin',然后格式化打印用户名和用户类型。注意字符串一定要加双引号
(五) awk PATTERN
awk PATTERN:根据pattern条件,先过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配每一行

图片 34

image.png


(2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
awk '/^UUID/{print $1}' /etc/fstab
awk '!/^UUID/{print $1}' /etc/fstab

图片 35

image.png


(3) relational expression: 关系表达式,结果为“真”才会被处理 真:结果为非0值,非空字符串
假:结果为空字符串或0值 
示例:
awk -F: 'i=1;j=1{print i,j}' /etc/passwd——判断'i=1,j=1'结果为非0,所以为真,给每一行都会打印'i=1,j=1'

图片 36

image.png


awk ‘!0’ /etc/passwd ——非0结果为真
awk ‘!1’ /etc/passwd ——结果为0,为假,不做后续处理
awk –F: '$3>=1000{print $1,$3}' /etc/passwd ——判断$3是否大于一千,如果大于一千则打印用户名和UID
awk -F: '$3<1000{print $1,$3}' /etc/passwd——原理同上
awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd ——最后一个字段是否为/bin/bash,如果满足则打印用户名和最后一个字段
awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd——最后一个字段是否是以/bash/结尾的,如果满足则打印
(4) line ranges:行范围
格式:startline,endline:/pat1/,/pat2/ 不支持直接给出数字
例子:
awk -F: '/root>/,/halt>/{print $1}' /etc/passwd ——判断以root开头,到以halt开头匹配的行

图片 37

image.png


awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd 
(5) BEGIN/END模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
示例:
awk -F: 'BEGIN{printf "username uidn"}'{printf "%-20s %-10dn "} END{printf "print end"}/etc/passwd

图片 38

image.png

图片 39

image.png


seq 10 | awk 'i=0'——i=0为假,不执行操作
seq 10 |awk 'i=1'——i=1为真,会打印

图片 40

image.png


seq 10 |awk 'i=!0'——非0为真,执行后续操作
seq 10 |awk 'i=!i'——i本身为0,因为之前没有赋值,但是加!表示非0,所以会打印1,当读入第二个数字是,非i为假,不打印,所以最后的输出结果为奇数

图片 41

image.png


如果想打印偶数, seq 10 |awk -v i=1 'i=!i'

图片 42

image.png


或者seq 10 |awk '!(i=!i)' 效果也是打印偶数
如果想知道输出的结果为真还是为假,可以 seq 10 |awk '{i=!i;print i}'

图片 43

image.png

||             逻辑或

awk:编辑器(主要处理有规律的文本)

六.awk数组

关联数组:
array[index-expression] 
index-expression:
(1) 可使用任意字符串;字符串要使用双引号括起来
(2) 如果某数组元素事先不存在,在引用时,awk会自动创建 此元素,并将其值初始化为“空串”
若要判断数组中是否存在某元素,要使用“index in array”格 式进行遍历
示例:
weekdays[“mon”]="Monday“

awk 'BEGIN{weekdays["mon"]="Monday"; weekdays["tue"]="Tuesday";print weekdays["mon"],weekdays[tue]}'

图片 44

image.png

图片 45

image.png


练习:
统计/etc/passwd中最后一个字段shell类型,并对每个类型计数
awk -F: '{line[$7] }END{for (i in line){print i,line[i] }}' /etc/passwd

图片 46

image.png


若要遍历数组中的每个元素,要使用for循环 
for(var in array) {for-body} 
注意:var会遍历array的每个索引 

例子:
awk -F: '!line[$7] ' /etc/passwd——作用是去重,'!'代表非的意思,相同的shell类型只打印一次。
原理:初始化为0,为假,但是通过"!",变为真,打印一次对应的shell类型,但是以后相同都不打印,执行完毕跳到下一行,继续执行新的shell类型的打印。

图片 47

image.png


awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"] ="Tuesday";for(i in weekdays) {print weekdays[i]}}'
***注意面试常考题:netstat -tan | awk '/^tcp/{state[$NF] }END {for(i in state) { print i,state[i]}}'
awk '{line[$1] }END{for(i in line) {print i,line[i]}}' access_log

图片 48

image.png


取出访问的ip地址,并统计访问数量
netstat -tan|awk -F: '[[:space:]] ' '/^tcp{ip[$6 ]END{for(i in ip){print i,ip[i]}}'

图片 49

image.png


如果想要排序,则在后面加入|sort -nr -k2|awk '{print $1}'|head -10

awk -f script.awk  file

常用举例:

语法 %-width.precision format-specifier
printf(" %d t %s n ", $5 , $8 )
printf("|s|n", "hello") 右对齐
printf("|%-10s|n", "hello") 左对齐
printf("%*.*fn", 5, 3, myvar) 宽度5 精度3 打印myvar

四.awk中的printf命令

格式化输出:printf “FORMAT”, item1, item2, ...

  • (1) 必须指定FORMAT
  • (2) 不会自动换行,需要显式给出换行控制符,n
  • (3) FORMAT中需要分别为后面每个item指定格式符 
    格式符:与item一一对应
    %c: 显示字符的ASCII码
    %d, %i: 显示十进制整数
    %e, %E:显示科学计数法数值
    %f:显示为浮点数
    %g, %G:以科学计数法或浮点形式显示数值
    %s:显示字符串
    %u:无符号整数
    %%: 显示%自身 
    修饰符: #[.#]:
    第一个数字控制显示的宽度;
    第二个#表示小数点后精度,%3.1f
    -: 左对齐(默认右对齐)
    %-15s :显示数值的正负符号 % d

 

布尔操作符:

|| 逻辑或Logical OR
&& 逻辑与Logical AND
! 逻辑非Logical NOT
先执行关系操作符再执行布尔操作符

七.awk函数

数值处理: rand():返回0和1之间一个随机数
awk 'BEGIN{print rand()}'——显示固定的值,并且为0和1之间的值
awk 'BEGIN{srand(); for (i=1;i<=10;i )print int(rand()*100) }' 

图片 50

image.png


字符串处理:
• length([s]):返回指定字符串的长度
• sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹 配的内容替换为s
echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
• gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换 为s所表示的内容
echo "2008:08:08 08:08:08" | awk ‘gsub(/:/,“-",$0)'
• split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存 至array所表示的数组中,第一个索引值为1,第二个索引值为2,…
netstat -tan | awk '/^tcp>/{split($5,ip,":");count[ip[1]] } END{for (i in count) {print i,count[i]}}'
练习:
统计男生的总分数和平均数,以及女生的总分数和平均数

图片 51

image.png


方法1:
awk '{total[$3] =$2;num[$3] }END{for(name in total){print name,total[name],total[name]/num[name]}}'

图片 52

image.png


方法2:awk '{if($3 == "male"){msum =$2;mnum }else{fsum =$2;fnum }}END{printf "msum=%d mavg=%.2fn fsum=%d favg=%.2fn",msum,msum/mnum,fsum,fsum/fnum }' score.txt

图片 53

image.png


(2)自定义函数 
格式: function name ( parameter, parameter, ... ) {
statements return expression
}
示例:
cat a.txt
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{
print max(a,b)}
awk -v a=10 -v b=20 –f a.txt

图片 54

image.png


(3)system命令 
空格是awk中的字符串连接符,如果system中需要使用awk中 的变量可以使用空格分隔,或者说除了awk的变量外其他一律 用""引用起来。
awk 'BEGIN{system("hostname") }'

图片 55

image.png


awk 'BEGIN{score=100; system("echo your score is " score) }'

图片 56

image.png


awk -v hi="haha" 'BEGIN{system("echo " hi)}'

图片 57

image.png


str="hello,mage" ;awk -v hi="$str" 'BEGIN{system("echo "hi)}'

图片 58

image.png

awk '{print " "}' /etc/passwd                                           //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本

关系操作符和布尔操作符

六.awk控制语句

(1) if-else语句
语法:if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2} else{statement3} 
使用场景:对awk取得的整行或某个字段做条件判断 
示例:
awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd

图片 59

image.png


awk -F : '{if($NF=="/bin/bash")print $1,$3 }' /etc/passwd——最后一个字段是否为/bin/bash,如果满足,则打印

图片 60

image.png


awk -F: '{if($3>=1000){printf username="common user %-20s %-10dn " ,$1,$3}else{printf username="sysuser or sysadmin %-20s %-10dn" ,$1,$3}}' /etc/passwd

图片 61

image.png


也可写成 awk -F: '{if ($3>=1000)printf usrename="common user %-20sn" ,$1;else printf username="sysuser or root %-20sn" ,$1}' /etc/passwd
df -h |awk -F: '/^/dev/{print $1}'|awk '$NF>10{print $NF}'

图片 62

image.png


awk 'BEGIN{test=680;if(test>=680)print "you can go to qinghua";else if (test<680$$test>=600)print "you can go to fudan";else print"you can go home"}'

图片 63

image.png


(2)while循环 
语法:while(condition){statement;…}  条件“真”,进入循环;条件“假”,退出循环 使用场景: 对一行内的多个字段逐一类似处理时使用 对数组中的各元素逐一处理时使用 
示例:
awk '/^[[:space:]]/linux16/{i=1;while (i<=NF){print $i,length($i);i }}' /etc/grub2.cfg
解释:首先规定是以空格开头并后跟linux16的行,然后判断字段数是否小于等于最后一个字段数,如果满足条件,就打印字段内容和字段的长度。然后去匹配下一行,并且重新从i=1赋值,继续判断循环

图片 64

image.png


awk '/^[[:space:]]linux16/{i=1;while (i<=NF){if length($i)>=10{print $i length($i)};i }}' /etc/grub2.cfg

图片 65

image.png


练习:
打印1到10,显示数字是奇数还是偶数
seq 10|awk '{i=1;while(i<=NF){if ($i%2==0)print $i,"oushu";else print $i,"jishu";i }}'

图片 66

image.png


(3)do-while循环 
语法:do {statement;…}while(condition) 
意义:无论真假,至少执行一次循环体
示例:
计算1加到100
方法1:
awk 'BEGIN{ total=0;i=0;do{ total =i;i ;}while(i<=100);print total}'
方法2:
echo {1..100}|tr ' ' ' '|bc
方法3:
seq -s ' ' 100|bc
方法4:
for ((sum=0;i=1;i<=100;i ));do let sum =i;done echo $sum

图片 67

image.png


方法5:
awk 'BEGIN{i=1;sum=0;while(i<=100){sum =i;i } print $sum}'
方法6:
awk 'BEGIN{for(i=1;i<=100;i ){sum =i}print sum}'

图片 68

image.png


(4)for循环 
语法:for(expr1;expr2;expr3) {statement;…} 
常见用法: for(variable assignment;condition;iteration process) {for-body} 
特殊用法:能够遍历数组中的元素
语法:for(var in array) {for-body} 
示例:
awk '/^[[:space:]]*linux/{for(i=1;i<=NF;i ){print $i length($i)}}'——寻找是否以空格开头,并后跟linux16的行,打印每个字段的内容,并显示字段的长度
(5)switch语句 
语法:
switch(expression) {case VALUE1 or /REGEXP/:
statement1; case VALUE2 or /REGEXP2/: statement2; ...; default: statementn}
break和continue
awk 'BEGIN{sum=0;for(i=1;i<=100;i ) {if(i%2==0)continue;sum =i}print sum}'
效果是打印奇数,并相加求和
如果想打印偶数
awk 'BEGIN{sum=0;for(i=1;i<=100;i ){if(i%2==0)continue;sum =i}print sum}'

图片 69

image.png


如果将continue换成break,效果是

图片 70

image.png


原因:break 的功能是如果满足条件,则跳出整个循环,不再执行,所以第一个数为1,属于奇数,满足条件,直接退出,显示结果为0
而计算偶数时,因为1为奇数,不满足条件,继续计数,直到第二个数进来,满足条件,则退出整个循环
练习:判断i是否等于50,如果等于退出循环,不再计算
awk 'BEGIN{sum=0;for(i=1;i<=100;i ) {if(i==50)break;sum =i}print sum}'

图片 71

image.png


next: 提前结束对本行处理而直接进入下一行处理(awk自身循环)
练习:
(1)awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd——判断uid是否为偶数,是偶数则打印

图片 72

image.png


(2)用next打印用户名打印偶数行(etc/passwd)
awk -F: '{if(NR%2!=0)next;print NR,$1,$3}' /etc/passwd

图片 73

image.png

3038/cupsd                   1     

格式化打印:

printf ( format-expression [, arguments] )
c ASCII 字符
d 十进制整数
f 浮点格式
s 字符串
x 无符号十六进制

示例:

(1)awk -F: '{print "%s" ,$1}' /etc/passwd——printf命令本身不具有换行命令,所以不加n,就不会自动换行

图片 74

image.png

(2) awk -F : '{printf "%sn",$1}' /etc/passwd

图片 75

image.png


(3)awk -F : '{printf "%s %dn" ,$1,$3}' /etc/passwd

图片 76

image.png

(4)awk -F: '{printf "%-30s %-30dn" ,$1,$3}' /etc/passwd

图片 77

image.png


(5)awk -F: '{printf "%-30s %-10.3f" ,$1,$3}'
/etc/passwd

图片 78

image.png


(6)awk -F: '{printf "username: %-20s uid: %-10dn" ,$1,$3}' /etc/passwd

图片 79

image.png


(7)awk -F: 'BEGIN{print "username uid"}{printf "%-20s %-10dn" ,$1,$3}' /etc/passwd

图片 80

image.png

(8) awk -F: 'BEGIN{printf "username uidn-----------n"}{printf "%-20s %-10dn" ,$1,$3}' /etc/passwd

图片 81

image.png


(9)df| grep "/dev/"|awk '{printf " username: %-20s use: %-10sn" ,$1,$5}'

图片 82

image.png

&& || 

系统变量:

FS 输入定义字段分隔符,默认为一个空格field seprator
OFS 输出的字段分隔符,默认为一个空格
awk 'BEGIN{FS=":";OFS="T"}{print $1,$2}' a.txt
RS 输入记录分隔符,默认为一个换行符
ORS 输出的记录分隔符,默认为一个换行符
awk 'BEGIN{RS="t";ORS=" "}{print $1,$2}' a.txt
NR 行数
awk '{print NR}' a.txt
FNR 行数,多文件操作时会重新排序
awk '{print FNR}' a.txt ming
NF 字段的个数,$NF表示最后一个字段
awk 'BEGIN{FS=":"}{print NF}' a.txt
FILENAME 文件名
awk '{print FILENAME}' a.txt

ls -l|awk 'NR!=1 && !/^d/{sum[$3] =$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s n",i," ",sum[i]/1024/1024,"MB"}'

程序模型:

打印:awk '{print}' a.txt
打印指定内容:awk '{print "hello",5}' a.txt
i 表示先赋值再加1
i表示先加1再赋值
awk 'BEGIN{i=6}{print i}' a.txt
awk 'BEGIN{i=6}{print i }' a.txt
BEGIN读入文本之前的操作
awk '{print i }END{print "hhh"}' a.txt
END读入文本之后的操作

-f指定脚本文件

awk过滤

通过 /xxx|xxx|xxx/ 来进行过滤

[root@rhel6 script]# df -hP | awk -F '%' '/usr|tmp|var/{print $1}'
tmpfs                     1.9G     0  1.9G   0
/dev/mapper/VG01-lv_tmp   3.8G   81M  3.6G   3
/dev/mapper/VG01-lv_usr   4.7G  2.0G  2.5G  44
/dev/mapper/VG01-lv_var   4.7G  573M  3.9G  13
[root@rhel6 script]# df -hP | awk -F '%' '/usr|tmp|var/{print $2}'
 /dev/shm
 /tmp
 /usr
 /var

 

 

*注意: awk的表达式需要使用单引号''

//纯字符匹配   !//纯字符不匹配   ~//字段值匹配    !~//字段值不匹配   ~/a1|a2/字段值匹配a1或a2   

awk -F

格式:-F'[:#/@¥$%]'   可以定义多个分隔符, 支持正则表达式     -F '[      :] '  使用空格和:分割, 表示可以有连续的空格或:

用法:awk -F"[@/t]" '{print $1,$2,$3}' <test

     以@,Tab键分割test文件的每一行,并输出第一、二、三列。

 

案例: 获取每个分区的Use空间

[root@rhel6 script]# df -Ph
Filesystem                Size  Used Avail Use% Mounted on
/dev/mapper/VG01-lv_root  3.8G  510M  3.1G  14% /
tmpfs                     1.9G     0  1.9G   0% /dev/shm
/dev/sda1                 477M   88M  364M  20% /boot
/dev/mapper/VG01-lv_home  1.9G  3.7M  1.8G   1% /home
/dev/mapper/VG01-lv_opt   1.9G  139M  1.7G   8% /opt
/dev/mapper/VG01-lv_tmp   3.8G  7.9M  3.6G   1% /tmp
/dev/mapper/VG01-lv_usr   4.7G  2.0G  2.6G  44% /usr
/dev/mapper/VG01-lv_var   4.7G  509M  4.0G  12% /var
[root@rhel6 script]# df -h | awk 'NR==3 {print $(NF-1)}' | awk -F '[%]' '{print $1}'
14

过滤出mysql端口

[root@rhel6 script]# netstat -lntup | grep 3306 | awk -F "[ :] " '{print $5}'
3306
[root@rhel6 script]# netstat -lntup | grep 3306 
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      16463/mysqld        

 

ls -l|awk 'BEGIN{sum=0} !/^d/{sum =$5} END{print "total size is:",int(sum/1024),"KB"}'         //int是取整的意思

模式匹配:

当匹配到//里的正则表达式后才执行后面命令
awk '/aaa/{print i,"hhh"}' a.txt
打印第一个和第二个字段:$0表示所有
awk '{print $1,$2}' a.txt
指定字段变量:
awk 'BEGIN{a=2}{print $a}' a.txt

awk -F ';' '{}'
-F指定分隔符
n 换行符
t TAB键
r 回车

                                                                                                                  //ID大于100,A加1,否则B加1

awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="t" netstat.txt

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s %-10s n",NR,$1,$2,$3}'

}

 

s表示字符串类型

awk -F: '{print ($3>100 ? $3":tyes":$3":tno")}'  /etc/passwd

{}           命令代码块,包含一条或多条命令

awk -F":" '$3<=1{print $3}' /etc/passwd                         //小于等于

n           换行符

7 x 2

==         等于,必须全部相等,精确比较

ls -l|awk 'BEGIN{sum=0} !/^d/{sum =$5} END{print "total size is:",sum/1024,"KB"}'

awk -F":" '$1=="mysql"{print $3}' /etc/passwd  

small

small

awk -F":" '$3>1000{print $3}' /etc/passwd                      //大于

awk '/[2][7][7]*/{print $0}' /etc/passwd               //匹配包含27为数字开头的行,如27,277,2777...

OFS       输出字段分隔符, 默认也是空格,可以改为制表符等

BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符

awk手册

-8长度为8个字符

第三个字段输出字符串类型(长度为10)

7 0 4

①在命令代码块中直接输出    route -n|awk 'NR!=1{print > "./fs"}'   

awk '{print "a"}'   /etc/passwd                                        //输出相同个数的a行,一行只有一个a字母

route -n|awk 'NR!=1{print}'                                       //不显示第一行

netstat -anp|awk '{printf "%-8s %-8s %-10sn",$1,$2,$3}' 

mysql        199 

10837                             1     

awk -F: '$1!~/mail/{print $1}' /etc/passwd          //不匹配

ls -l|awk 'NR!=1 && !/^d/{sum[$3] } END{for (i in sum) printf "%-6s %-5s %-3s n",i," ",sum[i]}'   

awk命令形式:

awk '{print NR,$0}' /etc/passwd                                 //输出每行的行号

/[0-9][0-9] /   两个或两个以上数字

awk -F'[:#/]' '{print NF}' helloworld.sh                                               //指定三个分隔符,并输出每行字段数

&&      逻辑与

awk -F: '{print $1; print $2}'   /etc/passwd                   //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本

应用5

 awk学习 

NR          每行的记录号,多文件记录递增

特殊要点:

print & $0

-F'[:#/]'   定义三个分隔符

 

//匹配代码块

small

awk -F":" '$3<1{print $3}' /etc/passwd                            //小于

条件表达式

awk -F: 'NR==5 || NR==6{print}'  /etc/passwd       //显示第5行和第6行

'  '          引用代码块

应用2

 

 

awk -F: 'NR==5{print}'  /etc/passwd                         //显示第5行

root           374 

~            匹配,与==相比不是精确比较

awk -F":" '{if($1=="mysql") print $3}' /etc/passwd          //与上面相同 

7913                               1     

应用6

awk -F: '{if($3<100) next; else print}' /etc/passwd                         //小于100跳过,否则显示

awk '!/mysql|mail/{print}' /etc/passwd

awk -F: '$3 > 100 || $3 < 5' /etc/passwd  

           匹配时表示1个或1个以上

awk -F: '/mysql|mail/{print $3 10}' /etc/passwd                    //第三个字段加10打印 

awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='t' helloworld.sh           //制表符分隔输出前5个字段,并打印行号

FILENAME 文件名

 

格式化输出

awk -F: '{print NF}' /etc/passwd                                //显示每行有多少字段

awk -F":" '{print $1 $3}'  /etc/passwd                       //$1与$3相连输出,不分隔

 

printf表示格式输出

awk -F: '{print $NF}' /etc/passwd                              //将每行第NF个字段的值打印出来

awk '/mysql/{print $0}' /etc/passwd                   //三条指令结果一样

awk -F: 'BEGIN{i=1} {while(i<nf) print="" nf,$i,i }'="" etc="" passwd ="" <="" div="">

awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file

原文:

awk -F: '$3 $4 > 200' /etc/passwd

输出处理结果到文件

Bob     2415 40 57 62

awk -F: '{print ($3>100 ? "yes":"no")}'  /etc/passwd 

small

awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='t' helloworld.sh   //制表符分隔输出多字段

awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd       //逻辑或

 

awk -F":" '$3>=100{print $3}' /etc/passwd                     //大于等于

/[0-9][0-9]*/    一个或一个以上数字

 

awk -F: '$1~/mail/{print $1}' /etc/passwd           //$1匹配指定内容才显示

awk -F: 'BEGIN{A=0;B=0} {if($3>100) {A ; print "large"} else {B ; print "small"}} END{print A,"t",B}' /etc/passwd 

$1           每行第一个字段

awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd            //if...else...

awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd         //逻辑与,$1匹配mail,并且$3>8

large

7903                               1     

应用7

7 0 3

数值运算

BEGIN{

print 是awk打印指定内容的主要命令

netstat -anp|awk 'NR!=1{a[$6] } END{for (i in a) print i,"t",a[i]}'

②使用重定向进行输出           route -n|awk 'NR!=1{print}'  > ./fs

另一种形式

7 /root 6

IF语句

9833                               1     

9929                               1     

awk -F: 'BEGIN{i=1} {if(i<nf) print="" nr,nf,i ="" }'="" etc="" passwd=""   <="" span="">

$1 指指定分隔符后,第一个字段,$3第三个字段, t是制表符

awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd        

total size is 17487

//           匹配代码块,可以是字符串或正则表达式

LISTEN                            6     

//输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段

$0           表示整个当前行

awk '/mysql|mail/{print}' /etc/passwd

awk -F":" '{print $1,$3}'  /etc/passwd                       //多了一个逗号,$1与$3使用空格分隔

awk处理过程: 依次对每一行进行处理,然后输出

;          多条命令使用分号分隔

awk -F: '/mysql/{print $3*$4}' /etc/passwd                             //求乘积

 [-F|-f|-v]   大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value

Mike    2537 87 97 95

==   !=   >   >=  

 

统计/home目录下不同用户的普通文件的总数是多少?

awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd 

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

 

awk -F: '{if($1~/mail/) {print $1}}'  /etc/passwd                                   //全写

计算/home目录下,普通文件的大小,使用KB作为单位

!~           不匹配,不精确比较

应用4

awk -F'[:#]' '{print NF}'  helloworld.sh                                                  //指定多个分隔符: #,输出每行多少字段

打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),

awk -F: 'BEGIN{i=1} {if(i<nf) {print="" nr,nf}="" i ="" }'="" etc="" passwd<="" span="">

统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少

END      结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息

 

 

{print $1}               //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定

NF          字段数量变量

awk 'BEGIN{X=0} /^$/{ X =1 } END{print "I find",X,"blank lines."}' test 

统计/home目录下不同用户的普通文件的大小总size是多少?

awk -F: '/mail/,/mysql/{print}' /etc/passwd         //区间匹配

awk '/MemFree/{print $2/1024}' /proc/meminfo                  //除法

awk -F: '{print NR,NF,$NF,"t",$0}' /etc/passwd      //依次打印行号,字段数,最后字段值,制表符,每行内容

awk -F":" '{print $1 " " $3}'  /etc/passwd                  //$1与$3之间手动添加空格分隔

图片 83

awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd

awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh     //制表符分隔输出多字段

逻辑运算符

 

 

awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh                                 //输出前5个字段

 

应用3

t            制表符

数组

 

 ls -l|awk 'BEGIN{sum=0} !/^d/{sum =$5} END{print "total size is",sum}'                    //计算文件大小

 

netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6] } END{for (i in sum) printf "%-10s %-6s %-3s n", i," ",sum[i]}'

awk  -F: '{print $1,$3,$6}' OFS="t" /etc/passwd        //输出字段1,3,6,以制表符作为分隔符

FS          BEGIN时定义分隔符

awk -F: '$3 > 100' /etc/passwd    

 

awk -F: '{if($1~/mail/) print $1}' /etc/passwd     //与上面相同

 

I find 4 blank lines.

RS       输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)

应用1

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息

FNR        与NR类似,不过多文件记录不递增,每个文件都从1开始

awk 'BEGIN{math=0;eng=0;com=0;printf "Lineno.   Name    No.    Math   English   Computer    Totaln";printf "------------------------------------------------------------n"}{math =$3; eng =$4; com =$5;printf "%-8s %-7s %-7s %-7s %-9s %-10s %-7s n",NR,$1,$2,$3,$4,$5,$3 $4 $5} END{printf "------------------------------------------------------------n";printf "%-24s %-7s %-9s %-20s n","Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s n","Avg:",math/NR,eng/NR,com/NR}' test0

awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="t" netstat.txt        

 

 

awk '{print}'  /etc/passwd   ==   awk '{print $0}'  /etc/passwd  

awk -F: '{if($1~/mail/) print $1}' /etc/passwd                                       //简写

-F指定分隔符

[root@localhost home]# cat test0 

%格式化输出分隔符

small

Marry   2143 78 84 77

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

IF语句

awk '/mysql/' /etc/passwd

awk -F: '{print $1,$2,$3,$4,$5}' OFS='t' helloworld.sh                 //输出前5个字段并使用制表符分隔输出

awk -F: '{print NF}' helloworld.sh                                                       //输出文件每行有多少字段

netstat -anp|awk 'NR!=1{a[$6] } END{for (i in a) printf "%-20s %-10s %-5s n", i,"t",a[i]}'

7 root 1

7 root 5

Tom     2122 48 77 71

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s n",$1,$2,$3}'

输出成绩表

 awk -F: 'NF==4 {print }' /etc/passwd                       //显示只有4个字段的行

FS=":"

awk -F: 'NF>2{print $0}' /etc/passwd                       //显示每行字段数量大于2的行

awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd

awk '/MemFree/{print int($2/1024)}' /proc/meminfo           //取整

awk '/mysql/{print }' /etc/passwd

Jack    2321 66 78 45

 

awk '!/mysql/{print $0}' /etc/passwd                  //输出不匹配mysql的行

9523                               1     

输出分隔符OFS

必须用在{}中,且比较内容用()扩起来

while语句

!=           不等于,精确比较

awk -F":" '{print "Username:" $1 "tt Uid:" $3 }' /etc/passwd       //自定义输出  

一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格

本文由时时app平台注册网站发布于时时app平台注册网站,转载请注明出处:awk

关键词: