码迷,mamicode.com
首页 > 其他好文 > 详细

awk进阶

时间:2016-07-15 22:02:37      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:awk

awk:报告生成工具,能够将文本处理为比较直观理想的报表。主要是对文本结果的格式化,也能处理文本搜索,但是效率要比grep低的多的多。


用法格式:

awk [options] ‘script‘ file1,file2 . . .
‘PATTERN{ action }‘

一、分隔符:字段分隔符,行分隔符


-F: 输入分隔符,下面以:号为分隔符。

[root@node1 ~]#  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
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin

BEGIN模式:正式awk处理文本之前做一些准备工作。#必须在awk处理之前

[root@node1 ~]# awk -F: ‘BEGIN {print "Username Shell"} {print $1,$7}‘ /etc/passwd
Username Shell
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
[root@node1 ~]# awk  ‘BEGIN {FS=":"} {print $1,$7}‘ /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
uucp /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
gopher /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin

OFS:输出格式,OFS=***** 输出格式如下:

[root@node1 ~]# awk  ‘BEGIN {FS=":"; OFS="*****"} {print $1,$7}‘ /etc/passwd
root*****/bin/bash
bin*****/sbin/nologin
daemon*****/sbin/nologin
adm*****/sbin/nologin
lp*****/sbin/nologin
sync*****/bin/sync
shutdown*****/sbin/shutdown
halt*****/sbin/halt
mail*****/sbin/nologin
uucp*****/sbin/nologin
operator*****/sbin/nologin
games*****/sbin/nologin
gopher*****/sbin/nologin
ftp*****/sbin/nologin
nobody*****/sbin/nologin

END模式:

[root@node1 ~]# awk  ‘BEGIN {FS=":"; OFS=":"} {print $1,$7}  END{print "=========END=========="}‘ /etc/passwd
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
uucp:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
gopher:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
vcsa:/sbin/nologin
saslauth:/sbin/nologin
postfix:/sbin/nologin
sshd:/sbin/nologin
nginx:/sbin/nologin
apache:/sbin/nologin
=========END==========

完善一下

[root@node1 ~]# awk  ‘BEGIN {FS=":"; OFS=":"; print "Username  Shell"} {print $1,$7}  END{print "=========END=========="}‘ /etc/passwd
Username  Shell
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
lp:/sbin/nologin
sync:/bin/sync
shutdown:/sbin/shutdown
halt:/sbin/halt
mail:/sbin/nologin
uucp:/sbin/nologin
operator:/sbin/nologin
games:/sbin/nologin
gopher:/sbin/nologin
ftp:/sbin/nologin
nobody:/sbin/nologin
vcsa:/sbin/nologin
saslauth:/sbin/nologin
postfix:/sbin/nologin
sshd:/sbin/nologin
nginx:/sbin/nologin
apache:/sbin/nologin
=========END==========

NF显示字段:

[root@node1 ~]# df -lh |awk ‘{print NF}‘
7
1
5
6
6




二、正则表达式:/PATERN/只匹配符合条件的行。

例:显示以sh结尾的行

[root@node1 ~]# awk  ‘BEGIN {FS=":"; OFS=":"; print "Username  Shell"} /sh$/ {print $1,$7}  END{print "=========END=========="}‘ /etc/passwd
Username  Shell
root:/bin/bash
=========END==========

表达式:>, <,>-,<=,~,!~

匹配ID号大于50的账号

[root@node1 ~]# awk -F: ‘$3>=50 {print $1,$3}‘ /etc/passwd
nobody 99
vcsa 69
saslauth 499
postfix 89
sshd 74
nginx 498

匹配/bin/bash账号

[root@node1 ~]# awk -F: ‘$7~/bash/ {print $1,$3}‘ /etc/passwd
root 0
test1 500
test2 501

不匹配/bin/bash账号

[root@node1 ~]# awk -F: ‘$7!~/bash/ {print $1,$3}‘ /etc/passwd
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
uucp 10
operator 11
games 12
gopher 13
ftp 14
nobody 99
vcsa 69
saslauth 499
postfix 89
sshd 74
nginx 498
apache 48

三、printf

printf命令的使用格式:

printf fromat,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:显示宽度;

-:左对齐;

+:显示数值符号;

例子

[root@node1 ~]# awk -F: ‘{printf "%15s %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
            ftp 14
         nobody 99
           vcsa 69
       saslauth 499
        postfix 89
           sshd 74
          nginx 498
         apache 48
          test1 500
          test2 501

%u显示无符号整数,-%15s左对齐

[root@node1 ~]# awk -F: ‘{printf "%-15s %u\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
ftp             14
nobody          99
vcsa            69
saslauth        499
postfix         89
sshd            74
nginx           498
apache          48
test1           500
test2           501

五、算术操作符:

-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 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            True if the string x matches the regexp denoted by y.

x!~y            True if the string x does not match the regexp dented by y.


表达式建的逻辑关系符:

&&

||

 

例:显示ID号大于500并且是/bin/bash的账号。

[root@node1 ~]# awk -F:  ‘$3>=500 &&$7~/bash/ {printf "%-15s %i %s\n ",$1,$3,$7}‘ /etc/passwd
test1           500 /bin/bash
test2           501 /bin/bash


条件表达式:

selector?if-true-exp:if-false-exp


if selector;then 

   if-true-exp

else

   if-false-exp

fi


函数调用:

function_name(para1,para2)


六、常用的模式类型:

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

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

3、Ranges:指定的匹配范围,格式为Pat1,Pat2

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

5、Empty(空模式):匹配任意输入行;

常见的Action

1、Expression;

2、Control statements

3、Compound statements

4、Input statements

5、Output statements

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

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

模式匹配表达式:

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

例:打印abc开始到aaa结束所匹配的行内容

[root@node1 ~]# cat test1.sh
mmm
opq
abc 1
cde 2
aaa 3
mnt 4
abc 5
hello 6
are 7
aaa 8
haow 9
are 10
you 11
abc 12
hello 13
world 14
[root@node1 ~]# awk ‘/abc/,/aaa/ {print $0}‘ test1.sh
abc 1
cde 2
aaa 3
abc 5
hello 6
are 7
aaa 8
abc 12
hello 13
world 14

七、控制语句:

if-else

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

例子:如果用户的ID号是0,就是管理员。否则就是普通用户

[root@node1 ~]# 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
sync Common User
shutdown Common User
halt Common User
mail Common User
uucp Common User
operator Common User
games Common User
gopher Common User
ftp Common User
nobody Common User
vcsa Common User
saslauth Common User
postfix Common User
sshd Common User
nginx Common User
apache Common User
test1 Common User
test2 Common User

显示ID号大于500的用户总数

[root@node1 ~]# awk -F: -v sum=0 ‘{if ($3>=500) sum++} END{print sum}‘ /etc/passwd
2

while

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

主要目的是每一个片中进行循环,不是每一行哦。

[root@node1 ~]# awk -F: ‘{i=1;while (i<3) {print $i;i++}}‘ /etc/passwd
root
x
bin
x
daemon
x
adm
x
lp
x
sync
x
shutdown
x
halt
x
mail
x
uucp
x
operator
x
games
x
gopher
x
ftp
x
nobody
x
vcsa
x
saslauth
x
postfix
x
sshd
x
nginx
x
apache
x
test1
x
test2
x
[root@node1 ~]# 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
/sbin
/sbin/nologin
/var/adm
/sbin/nologin
/var/spool/lpd
/sbin/nologin
sync
sync
/sbin
/bin/sync
shutdown
shutdown
/sbin
/sbin/shutdown
halt
halt
/sbin
/sbin/halt
mail
mail
/var/spool/mail
/sbin/nologin
uucp
uucp
/var/spool/uucp
/sbin/nologin
operator
operator
/root
/sbin/nologin
games
games
/usr/games
/sbin/nologin
gopher
gopher
/var/gopher
/sbin/nologin
FTP User
/var/ftp
/sbin/nologin
nobody
Nobody
/sbin/nologin
vcsa
virtual console memory owner
/dev
/sbin/nologin
saslauth
"Saslauthd user"
/var/empty/saslauth
/sbin/nologin
postfix
/var/spool/postfix
/sbin/nologin
sshd
Privilege-separated SSH
/var/empty/sshd
/sbin/nologin
nginx
Nginx web server
/var/lib/nginx
/sbin/nologin
apache
Apache
/var/www
/sbin/nologin
test1
/home/test1
/bin/bash
test2
/home/test2
/bin/bash
[root@node1 ~]# awk -F: ‘{i=1;while (i<=3) {printf "%s", $i;i++;};printf "\n"}‘ /etc/passwd
rootx0
binx1
daemonx2
admx3
lpx4
syncx5
shutdownx6
haltx7
mailx8
uucpx10
operatorx11
gamesx12
gopherx13
ftpx14
nobodyx99
vcsax69
saslauthx499
postfixx89
sshdx74
nginxx498
apachex48
test1x500
test2x501

打印大于100的数值,每行显示

[root@node1 ~]# cat test2.sh
89 746 38 8489 99
55 34
857 7384 75492
88
56
13 83
[root@node1 ~]# awk ‘{i=1;while (i<=NF) {if ($i>=100) print $i;i++}}‘ test2.sh
746
8489
857
7384
75492

do-while

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

先执行一次,不管条件满足与否至少执行一次循环体。

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

for

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

[root@node1 ~]# awk -F: ‘{for(i=1;i<3;i++) print $i}‘ /etc/passwd
root
x
bin
x
daemon
x
adm
x
lp
x
sync
x
shutdown
[root@node1 ~]# awk -F: ‘{for(i=1;i<NF;i++) {if (length($i)>=4) {print $i}}}‘ /etc/passwd
root
root
/root
/bin
daemon
daemon
/sbin
/var/adm
/var/spool/lpd
sync
sync
/sbin
shutdown
shutdown
/sbin
halt
halt
/sbin
mail
mail
/var/spool/mail
uucp
uucp
/var/spool/uucp
operator
operator
/root
games
games
/usr/games
gopher
gopher
/var/gopher


本文出自 “奋斗中的老兵” 博客,请务必保留此出处http://jiaxu201.blog.51cto.com/4569604/1826810

awk进阶

标签:awk

原文地址:http://jiaxu201.blog.51cto.com/4569604/1826810

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!