一、awk简介

awk是由3个人开发的:Aho, Weinberger, Kernighan;该功能主要是用来生成报告和格式化文本输出。它有多个版本:New awk(nawk),GNU awk( gawk)。我们通常在linux上使用的awk是基于GNU的awk。awk不只是一个命令,其真实,为一门语言,循环、数组、条件判断样样功能都有,功能非常强大,当然功能强大了,那么必定复杂。

二、基本用法:

awk [options] ‘program’ var=value file…
awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{action;… }’ file …
awk [options] -f ‘a program file’ file … (读取一个存有awk规则预存文件,再对指定文件进行处理) 这种用法,最后再说


options:


-F 指明输入时用到的字段分隔符(awk默认的分隔符就是空白字符)
-v var=value: 自定义变量 (awk的变量也分内置变量和自定义变量两种)


内置变量:


FS:输入字段分隔符,默认为空白字符
OFS:输出字段分隔符,默认为空白字符
RS:输入记录分隔符,指定输入时的换行符
ORS:输出记录分隔符,输出时用指定符号代替换行符
NF:字段数量
NR:记录号
FNR:各文件分别计数,记录号
FILENAME:当前文件名
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行所给定的各参数


注意:虽然为内置变量,但是内置变量也可以用-v来声明初始值

1、awk [options] ‘program’ var=value file…用法的详细说明

program: pattern{action statements;..} #program由pattern和action两部分来组成


pattern和action:


• pattern部分决定动作语句何时触发及触发事件(也可以理解为匹配,用来过滤记录的)BEGIN,END
• action statements对数据进行处理,放在{}内指明print, printf


分割符、域和记录:


• awk执行时,由分隔符分隔的字段(域)标记$1,$2..$n称为域标识。$0为所有域,注意:和shell中变量$符含义不同
• 文件的每一行称为记录(一般的一行被称作一条记录
• 省略action,则默认执行 print $0 的操作($0表示一整条记录,print表示打印输出的意思)


实例1,显示源输出的指定列:


  1. [root@newhostname /]# df | grep /dev/sd #先查看一下源标准输出
    /dev/sda1 1038336 162080 876256 16% /boot
    /dev/sdb3 3135488 135364 3000124 5% /mnt/xfs
    /dev/sdb2 3030800 9236 2847896 1% /mnt/ext4
    [root@newhostname /]# df | grep /sd | awk ‘{print $1”===”$5}’
    /dev/sda1===16%
    /dev/sdb3===5%
    /dev/sdb2===1%
    #$1为输出的第一列,$5为第5列,awk的默认字符是空表字符, 两列中间的等号为加入的字符串“===”

实例2,使用awk的内置变量:

  1. [root@newhostname /]# awk -v FS=’:’ ‘{print $1,FS,$3}’ /etc/passwd | head -5 #我们使用内置变量FS来作为分隔符
    root : 0
    bin : 1
    daemon : 2
    adm : 3
    lp : 4
    [root@newhostname /]# awk -F: ‘{print $1,FS,$3}’ /etc/passwd | head -5 #我们使用-F option来指定分隔符
    root : 0
    bin : 1
    daemon : 2
    adm : 3
    lp : 4
    由上面两个结果来看,其意义是一样的, 可以使用 -v 直接声明字段的分隔符,也可以用-F来指定。而在action内,变量是可以直接被调用的 ,注意,action内不要看走眼,如果是字符串的话,需要加“”“,直接输入的字符会当做变量来处理。

OFS变量的作用:

  1. [root@newhostname /]# awk -v FS=’:’ -v OFS=’:’ ‘{print $1,$3,$7}’ /etc/passwd | head -5 #OFS输出字段分隔符,默认为空白,这里我们指定为“:”
    root:0:/bin/bash
    bin:1:/sbin/nologin
    daemon:2:/sbin/nologin
    adm:3:/sbin/nologin
    lp:4:/sbin/nologin
    [root@newhostname /]# awk -v FS=’:’ ‘{print $1,$3,$7}’ /etc/passwd | head -5 #我们不指定OFS两段命令一对比,很明显,下面输出的使用的默认输出分隔符为空白。
    root 0 /bin/bash
    bin 1 /sbin/nologin
    daemon 2 /sbin/nologin
    adm 3 /sbin/nologin
    lp 4 /sbin/nologin

RS、ORS变量的应用:

  1. [root@newhostname zsfile]# cat 123.txt #文件的原输出
    dddd:112233:1000:1000 /home/bash:/bin/bash

  2. [root@newhostname zsfile]# awk -v RS=’:’ ‘{print }’ ./123.txt #定义RS变更记录分隔符(默认的分隔符是换行符)
    dddd
    112233
    1000
    1000 /home/bash
    /bin/bash

  3. [root@newhostname zsfile]# awk -v RS=’:’ -v ORS=’|-|’ ‘{print }’ ./123.txt #我们定义ORS来改变输出的分隔符
    dddd|-|112233|-|1000|-|1000 /home/bash|-|/bin/bash
    |-|[root@newhostname zsfile]#

RS的意义是改变处理文本之前的记录分隔符,当处理完记录之后,输出记录分隔符(ORS)如果未定义,则还是现实原来默认的记录分隔符去显示,即默认的换行符。


实例3,NF字段数量,NR行号变量,FNR分文件行号变量,FILENAME当前的文件名,ARGC命令行参数的个数

  1. [root@newhostname zsfile]# vim 1111
    [root@newhostname zsfile]# cat 1111
    aa bb cc dd ee
    11 22 33 44 55
    33 22 11 ss 44
    [root@newhostname zsfile]# awk ‘{print NR,NF}’ 1111 #NR表示第几行,NF为列的总数
    1 5
    2 5
    3 5

  2. [root@newhostname zsfile]# awk ‘{print NR,$NF}’ 1111 #$NF表示最后一列
    1 ee
    2 55
    3 44

  3. [root@newhostname zsfile]# awk ‘{print NR,$NF}’ 1111 123.txt #如果使用awk同时对多个文件进行处理,那么使用NR,最后的出列结果会合并成1个,而不会按文件分开,如果要按文件分开,要是用FNR
    1 ee
    2 55
    3 44
    4 /home/bash:/bin/bash

  4. [root@newhostname zsfile]# awk ‘{print FNR,$NF}’ 1111 123.txt #使用FNR按文件分开
    1 ee
    2 55
    3 44
    1 /home/bash:/bin/bash

  5. [root@newhostname zsfile]# awk ‘{print FILENAME,FNR,$NF}’ 1111 123.txt #FILENAME 在输出列输出文件的名字
    1111 1 ee
    1111 2 55
    1111 3 44
    123.txt 1 /home/bash:/bin/bash

  6. [root@newhostname zsfile]# awk ‘{print ARGC}’ 1111 #awk 表示一个参数 1111表示一个参数
    2
    2
    2
    [root@newhostname zsfile]# awk ‘{print ARGC}’ 1111 123.txt #awk表示1个参数,1111表示一个参数,123.txt表示一个参数,所以输出结果为“3”
    3
    3
    3
    3

  7. [root@newhostname zsfile]# awk BEGIN {print ARGC}’ /etc/fstab /etc/inittab
    3

变量是可以在action内定义的,但是不利于写shell脚本,因为一般action都是有单引号引起来的,在shell内单引号是强引用,无法很好地使用shell变量(是shell变量非awk变量)


printf的用法(格式化字符串输出,比print更强大的输出方式,printf实际上也是一个linux命令):


printf的格式和特性:printf “FORMAT”, item1, item2, …


(1) 必须指定FORMAT
(2) 不会自动换行,需要显式给出换行控制符,\n
(3) FORMAT中需要分别为后面每个item指定格式符


printf的格式符:


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


修饰符:


#[.#]:第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f
-: 左对齐(默认右对齐,对字符串你操作) %-15s
+:显示数值的正负符号 %+d


下面我们来用printf来举例:


printf字符串的格式化

  1. [root@joker-6-01 ~]# awk -F: ‘{printf “%s - “,$1}’ /etc/passwd #printf 后面的%s代表的是$1,在这里$1不仅可以是列,还可以是变量、字符串
    root - bin - daemon - adm - lp - sync - shutdown - halt - mail - uucp - operator - games - gopher - ftp - nobody - dbus - usbmuxd - rpc - rtkit - avahi-autoipd - vcsa - abrt - rpcuser - nfsnobody - haldaemon - ntp - apache - saslauth - postfix - gdm - pulse - sshd - tcpdump - ee - rr - wang - wang1 - wang2 - wang3 - [root@joker-6-01 ~]#

  2. 由以上输出我们可以看出,printf是不会换行的,如果要换行 printf引号呢最后要添加\n

  3. [root@joker-6-01 ~]# awk -F: ‘{printf “%s - \n”,$1}’ /etc/passwd | head -5 #添加\n,(因为条目太多,所以在这里我把条目限定在了5行,后面的示例也都这样操作)
    root -
    bin -
    daemon -
    adm -
    lp -

  4. 每一条记录执行完都会换行

printf的使用修饰符

  1. [root@joker-6-01 ~]# awk -F: ‘{printf Username:%s,UID:%d\n”,$1,$3}’ /etc/passwd | head -5
    Username:root,UID:0
    Username:bin,UID:1
    Username:daemon,UID:2
    Username:adm,UID:3
    Username:lp,UID:4

  2. 在这里我们使用字符串的格式化输出,但是输出结果并不直观,下面我们可以使用修饰符进行分割。

  3. [root@joker-6-01 ~]# awk -F: ‘{printf Username:%-20sUID:%d\n”,$1,$3}’ /etc/passwd | head -5 #%-20s :20表示最大长度,“-”表示左对齐
    Username:root UID:0
    Username:bin UID:1
    Username:daemon UID:2
    Username:adm UID:3
    Username:lp UID:4

  4. 输出的结果很明显

  5. [root@joker-6-01 ~]# awk -F: ‘{printf Username:%20sUID:%d\n”,$1,$3}’ /etc/passwd | head -5 #不加“-”的表示默认右对齐,在这里只是一个示例,没有任何意义
    Username: rootUID:0
    Username: binUID:1
    Username: daemonUID:2
    Username: admUID:3
    Username: lpUID:4

  6. 在这种环境下,使用右对齐显示不是我们要的,在这里我只是想标清楚,什么是左对齐,什么是右对齐

  7. 接下来我们示范一下浮点数的表示方法

  8. [root@joker-6-01 ~]# awk -F: BEGIN{printf”%f\n”,3.1234}’
    3.123400
    [root@joker-6-01 ~]# awk -F: BEGIN{printf”%f\n”,3.1}’
    3.100000

  9. 使用%f默认会甩出6位的小数位,那么我们使用修饰符来限定位数,关于BEGIN,在这里的意思是只执行一遍指令,并且不需要读取文件,BEGIN的真正含义是在读取文件之前执行的操作,我们在这里先不管,后面会讲解

  10. [root@joker-6-01 ~]# awk -F: BEGIN{printf”%8.3f\n”,3.1}’ #8代表整数字符的宽度;.3代表小数的位数
    3.100
    [root@joker-6-01 ~]# awk -F: BEGIN{printf”%08.3f\n”,3.1}’ #08指如果整数位不足8位用0来代表空白
    0003.100

  11. 浮点数的修饰一般我们做普通运维用不到,一般用的比较多的还是%s %d这两个

AWK的运算符:在action内执行


算术操作符:


x+y, x-y, xy, x/y, x^y, x%y
-x: 转换为负数
+x: 转换为数值
字符串操作符:没有符号的操作符,字符串连接


赋值操作符:


=, +=, -=, =, /=, %=, ^=
++, —


比较操作符:


==, !=, >, >=, <, <=
模式匹配符:
~:左边是否和右边匹配包含 !~:是否不匹配


逻辑操作符:


与&&,或||,非!


 

不多说了,直接举例:

  1. [root@joker-6-01 ~]# awk -F: $0 ~ /root/{print $1}’ /etc/passwd # “~” 匹配运算符
    root
    operator

  2. 大括号前面的这一部分,代表的就是最开始所说的“pattern”,这部分的的实际作用就是用来匹配指定记录。上面的含义就是 $0(整条记录)内是否有匹配root的记录,我们在这里使用的“root”是一个实际的字符串,在这里我们也可以使用正则表达式来匹配,我们使用/regex/的形式来表示匹配,我们来做个演示。

  3. [root@joker-6-01 ~]# cat /etc/passwd | tail -10 #现实passwd的后10行,我们将对这段字符进行操作
    gdm:x:42:42::/var/lib/gdm:/sbin/nologin
    pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    tcpdump:x:72:72::/:/sbin/nologin
    ee:x:500:500:dd,ff,aa,qwe:/home/ee:/bin/bash
    rr:x:501:502::/home/rr:/bin/bash
    wang:x:1010:1010::/app/wangs:/bin/bash
    wang1:x:1014:1011::/home/wang1:/bin/bash
    wang2:x:1012:1012::/home/wang2:/bin/bash
    wang3:x:1013:1013::/home/wang3:/bin/bash

  4. [root@joker-6-01 ~]#cat /etc/passwd | tail -10| awk $0 ~ /^t.+n$/{print $0}’
    tcpdump:x:72:72::/:/sbin/nologin

  5. “/^t.+n$/” 代表的开头是“t”结尾为“n”的记录。

  6. 我们再来做一个不配“t”结尾为“n”的记录的示例:

  7. [root@joker-6-01 ~]# cat /etc/passwd | tail -10 | awk $0 !~ /^t.+n$/{print $0}’ # “!~” 表示不匹配,也就是说,不匹配的记录,awk认为是我们需要的数据
    gdm:x:42:42::/var/lib/gdm:/sbin/nologin
    pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    ee:x:500:500:dd,ff,aa,qwe:/home/ee:/bin/bash
    rr:x:501:502::/home/rr:/bin/bash
    wang:x:1010:1010::/app/wangs:/bin/bash
    wang1:x:1014:1011::/home/wang1:/bin/bash
    wang2:x:1012:1012::/home/wang2:/bin/bash
    wang3:x:1013:1013::/home/wang3:/bin/bash

  8. 我们再action内做算数运算
    [root@joker-6-01 ~]# awk BEGIN{print 2+2}’
    4
    [root@joker-6-01 ~]# awk BEGIN{print 23}’
    6
    [root@joker-6-01 ~]# awk BEGIN{print 2%3}’
    2
    [root@joker-6-01 ~]# awk BEGIN{print 2*
    3}’
    8

  9. 然后我这里有个坑:
    [root@joker-6-01 ~]# awk BEGIN{i=0;print ++i,i}’ #限制性i+1 然后在输出i
    1 1
    [root@joker-6-01 ~]# awk BEGIN{i=0;print i++,i}’ #先输出 i 然后再执行 i+1,所以这两个结果不同
    0 1

  10. [root@joker-6-01 zsfile]# awk -F: $3 == 0 /etc/passwd #以:为分隔符,如果第三列为0,那么打印这一样,省略action则表示打印整条记录
    root:x:0:0:root:/root:/bin/bash

  11. 逻辑运算符的使用方法
    [root@joker-6-01 zsfile]# awk -F: $3 >=0 && $3<=100{print $1}’ /etc/passwd #uid大于等于0,小于等于100的记录,打印第一列
    root
    bin
    daemon
    adm
    lp
    sync
    shutdown
    halt
    mail
    uucp
    operator
    games
    gopher
    ftp
    nobody
    dbus
    rpc
    vcsa
    rpcuser
    haldaemon
    ntp
    apache
    postfix
    gdm
    sshd
    tcpdump

  12. [root@joker-6-01 zsfile]# awk -F: ‘!($3==0) && NR==3 {print $1}’ /etc/passwd #这句表达的意思:取第三行,如果第三列不等于0,就打印该行,否则不操作。
    daemon

2、awk [options] ‘BEGIN{ action;… } pattern{ action;… } END{action;… }’ file …的详细使用方法

BEGIN/END模式
BEGIN{}: 仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次


示例:

  1. [root@joker-6-01 zsfile]# awk -F : BEGIN {printf USER %-16sUSERID\n”,””}/^(t|p)/ {printf “%-20s %s\n”,$1,$3}END{printf end%-18sfile\n”,””}’ /etc/passwd
    执行结果:
    USER USERID #BEGIN开始打印一行
    postfix 89
    pulse 497
    tcpdump 72
    end file #END执行完后打印

  2. if的示例:

三、awk的高阶用法

一般这种模式是用来处理一些判断或者循环事件的。


1、awk的判断语句(一般在action内使用)


awk控制语句——if-else


if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else{statement3}


awk的三元表达式,可用作变量赋值的判断


selector?if-true-expression:if-false-expression

  1. [root@joker-6-01 zsfile]# awk -F: ‘{if($3 >=100)print $1,$3}’ /etc/passwd #判断如果第三列大于100(passwd中的uid值),打印这个记录的第一列和第三列
    usbmuxd 113
    rtkit 499
    avahi-autoipd 170
    abrt 173
    nfsnobody 65534
    saslauth 498
    pulse 497

  2. 我们定义两个变量,分别判断两个值的大小
    [root@joker-6-01 zsfile]# awk BEGIN{a=1;b=2;if(a>b){print ok”}else if(a==b){printa=b”}else {print no”}}’
    no
    [root@joker-6-01 zsfile]# awk BEGIN{a=2;b=2;if(a>b){print ok”}else if(a==b){printa=b”}else {print no”}}’
    a=b
    [root@joker-6-01 zsfile]# awk BEGIN{a=2;b=1;if(a>b){print ok”}else if(a==b){printa=b”}else {print no”}}’
    ok

  3. 三元表达式的用法:
    [root@joker-6-01 zsfile]# awk BEGIN{a=1;b=2;a>b?a=3:b=3;print a,b}’
    1 3


 

2、while循环


while(condition){statement;…}


do-while循环


do {statement;…}while(condition)
这种形式的循环表达的意思是,无论什么样的条件都会先执行一次循环,然后再判断while条件的真假。

  1. [root@joker-6-01 zsfile]# awk -v a=4 BEGIN{while(a>0){ print a;a-=1 }}’ #我没有想出一个应用场景啊,就用一个简单循环代替了。语法就是这么写
    4
    3
    2
    1

  2. d0-while用法
    [root@joker-6-01 zsfile]# awk BEGIN{total=0;i=0;do{total+=i;i++}while(i<=100);print total}’ #计算前1-100的和
    5050


 

3、for循环


for(expr1;expr2;expr3) {statement;…}
for(variable assignment;condition;iteration process){for-body}

  1. 两种语法:1for i in array #这种方法,待会写了数组再谈
    2for( i=x;i<=100;i++)

  2. [root@newhostname zsfile]# awk ‘/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}’ /boot/grub2/grub.cfg #遍历一个文件
    linux16 7
    /vmlinuz-3.10.0-693.el7.x86_64 30
    root=/dev/mapper/centos_joker701-root 41
    ro 2
    rd.lvm.lv=centos_joker-7-01/root 32
    rd.lvm.lv=centos_joker-7-01/swap 32
    rhgb 4
    quiet 5
    linux16 7
    /vmlinuz-0-rescue-77b790ce63d24178bd4d95027a1bd2e9 50
    root=/dev/mapper/centos_joker701-root 41
    ro 2
    rd.lvm.lv=centos_joker-7-01/root 32
    rd.lvm.lv=centos_joker-7-01/swap 32
    rhgb 4
    quiet 5


 

4、switch语句(相当于shell内的case语句)


switch(expression) {case VALUE1 or /REGEXP/:statement1; case VALUE2 or /REGEXP2/: statement2;…; default: statementn}


break [n] 跳出整个循环
continue [n] 跳过本次循环执行下次循环
next 提前结束对本行处理而直接进入下一行处理(awk自身循环)

  1. [root@newhostname zsfile]# awk -F: ‘{if($3==0) next; print $1,$3}’ /etc/passwd | head -5 #打印非root用户
    bin 1
    daemon 2
    adm 3
    lp 4
    sync 5

这些控制语句是不是很眼熟,不论是什么语言都会有这些,只不过是表达形式的不同而已,原理都是一样的。


5、数组


awk的数组也分有序数组和关联数组两种
如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”

  1. awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}' #定义一个数组,并打印
  2. awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays) {print weekdays[i]}}' #便利一个数组的下标,注意,数组名不加[]表示数组下标的序列

6、awk的函数(常用的)


rand():返回0和1之间一个随机数,想用多少为的随机数只需init(rand()*num)即可,注意,如果要调用rand()函数,那么前面必须调用srand(),初始化一次随机值
length([s]):返回指定字符串的长度
sub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并将第一个匹配的内容替换为s
gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所表示的数组中,第一个索引值为1,第二个索引值为2,…

  1. [root@newhostname zsfile]# awk 'BEGIN{srand(); for (i=1;i&lt;=10;i++)print int(rand()*100) }' #输出10个100以内的随机数
  2. 52
  3. 68
  4. 13
  5. 38
  6. 95
  7. 28
  8. 59
  9. 45
  10. 84
  11. 19
  12. [root@newhostname zsfile]# echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$1)' #查找替换全部的:为-
  13. 2008-08-08 08:08:08
  14. [root@newhostname zsfile]# echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)' #查找替换第一个:为-
  15. 2008-08:08 08:08:08
  16. [root@newhostname zsfile]# netstat -tan | awk '/^tcp\&gt;/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}' #将第5列分割的字符串保存到数组ip中,并将有ip的下标变量付给count数组, 用for i in 遍历这个count并打印出ip
  17. 0.0.0.0 4
  18. 172.18.101.180 1</pre>
  19. <p style="padding-left: 60px;">7awk函数</p>
  20. <p style="padding-left: 90px;">格式:
  21. function name ( parameter, parameter, ... ) {
  22. statements
  23. return expression
  24. }</p>
  25. <p style="padding-left: 60px;">和其他语言的格式基本相同,用法也差不多,这里不多说了。</p>
  26. <p style="padding-left: 60px;">8awk中调用shell命令,可以使用system()函数</p>
  27. <pre class="EnlighterJSRAW" data-enlighter-language="null">[root@newhostname zsfile]# awk BEGIN'{system("hostname") }'
  28. newhostname

 

四、最后了,我们现在再说这种用法 :awk [options] -f ‘a program file’ file …

其实很简单就是讲awk的语句存到文件内,然后使用 awk -f来调用,就像shell调用shell脚本一样

  1. cat test_awk.awk
  2. #! /usr/bin/awk
  3. {if($3&gt;=1000)print $1,$3}
  4. [root@newhostname zsfile]# awk -f test_awk.awk /etc/passwd
  5. systemd-network:x:192:192:systemd Management:/:/sbin/nologin
  6. dbus:x:81:81:System bus:/:/sbin/nologin
  7. polkitd:x:999:997:User polkitd:/:/sbin/nologin
  8. colord:x:998:996:User colord:/var/lib/colord:/sbin/nologin
  9. libstoragemgmt:x:997:994:daemon for
  10. pulse:x:171:171:PulseAudio Daemon:/var/run/pulse:/sbin/nologin
  11. tss:x:59:59:Account by
  12. geoclue:x:994:989:User geoclue:/var/lib/geoclue:/sbin/nologin
  13. rpcuser:x:29:29:RPC User:/var/lib/nfs:/sbin/nologin
  14. nfsnobody:x:65534:65534:Anonymous User:/var/lib/nfs:/sbin/nologin
  15. sssd:x:993:988:User sssd:/:/sbin/nologin

输出一个文件内最大长度字段的长度,和这个字段的值

  1. [root@newhostname shell]# cat longest_field.sh
  2. #!/usr/bin/env awk -f
  3. #
  4. #********************************************************************
  5. #encoding -*-utf8-*-
  6. #Author: zhangshang
  7. #Date: 2018-01-04
  8. #URL: http://blog.vservices.top/myblog
  9. #QQ Numbers: 765030447
  10. #********************************************************************
  11. BEGIN {
  12. max=0
  13. }
  14. {
  15. split($0,field_record,FS);
  16. for(i in field_record)
  17. {if(length(field_record[i])&gt;max){
  18. max=length(field_record[i]);max_field=field_record[i]}
  19. }
  20. }
  21. END{
  22. print max_field,max
  23. }
  24. #max=i;
  25. [root@newhostname shell]# cat ~/112233 #查看文本
  26. aaa:asdf:ddddddddd
  27. z:asdfasdfasd:asdfasdfasdfasdf:asdfz:ddd
  28. cccccccccccccccccc:eeeeeee:1111111:
  29. [root@newhostname shell]# awk -F: -f longest_field.sh ~/112233 #awk调用脚本
  30. cccccccccccccccccc 18

 

文档更新时间: 2018-12-12 20:28   作者:张尚