三剑客:awk实战

 

1    awk实战基础入门精讲

1.1  awk命令格式:

awk指令由模式、动作、或者模式和动作的组合组成

模式既pattern,可以类似理解成sed的模式匹配,可以由表达式组成,也可以是两个正斜杠之间的政策表达式。比如NR==,这就是模式,可以把他理解位一个条件。

动作即action,是由在大括号里面的一条或多条语句组成,语句之间使用分号隔开。如awk使用格式

 

1.1.1 常见的模式类型:

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

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

3、Ranges: 指定的匹配范围,格式为pat1,pat2

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

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

1.1.2 常见的Action

1、Expressions:

2、Control statements

3、Compound statements

4、Input statements

5、Output statements

1.2  awk的执行过程

系统环境

[root@cobbler6 ~]# cat /etc/redhat-release
CentOS release 6.7 (Final)
[root@cobbler6 ~]# uname -r
2.6.32-573.el6.x86_64
[root@cobbler6 ~]# ll "which awk"
ls: cannot access which awk: No such file or directory
[root@cobbler6 ~]# ll `which awk`
lrwxrwxrwx. 1 root root 4 Oct  7 01:03 /bin/awk -> gawk
[root@cobbler6 ~]# awk --version
GNU Awk 3.1.7

示例文件:

[root@cobbler6 ~]# mkdir /server/files/ -p
[root@cobbler6 ~]# head /etc/passwd >/server/
files/   scripts/
[root@cobbler6 ~]# head /etc/passwd >/server/files/awkfile.txt
[root@cobbler6 ~]# cat awkfile.txt
cat: awkfile.txt: No such file or directory
[root@cobbler6 ~]# cat /server//files/awkfile.txt
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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

1.3  记录和域的概念

[root@cobbler6 files]# awk 'BEGIN{RS=":"}{print NR,$0}' awkfile.txt
1 root
2 x
3 0
4 0
5 root
6 /root
7 /bin/bash
bin
8 x 

awk眼中的文件,从头到尾一段连续的字符串,恰巧中间有些\n(回车换行符),为了方便人查看,就把RS的值设置为\n

[root@cobbler6 files]# awk 'BEGIN{RS=""}{print NR,$0}' awkfile.txt 
1 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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

[root@cobbler6 files]# awk 'BEGIN{RS=""}{print NR,$1,$3,#5}' awkfile.txt  
awk: cmd. line:1: BEGIN{RS=""}{print NR,$1,$3,#5}
awk: cmd. line:1:                             ^ syntax error

[root@cobbler6 files]# awk 'BEGIN{RS=""}{print NR,$1,$3,$5}' awkfile.txt 
1 root:x:0:0:root:/root:/bin/bash daemon:x:2:2:daemon:/sbin:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

企业案例1:计算文件中每个单词重复数量

1、单词弄成一列(排队)

sed -ri.bak 's#[:/0-9]+# #g' awkfile.txt

RS 替换\n

[root@cobbler6 files]# egrep -o "[a-zA-Z]+" awkfile.txt |sort|uniq -c

      3 adm
      1 bash
      5 bin
      2 daemon
      3 halt
      2 lp
      1 lpd
      3 mail
      6 nologin
      3 root
     12 sbin
      3 shutdown
      3 spool
      3 sync
      3 uucp
      4 var
     10 x

RS 空值

[root@cobbler6 files]# sed -ri.bak 's#[:/0-9]+# #g' awkfile.txt

去掉[:/0-9]

[root@cobbler6 files]# cat awkfile.txt
root x root root bin bash
bin x bin bin sbin nologin
daemon x daemon sbin sbin nologin
adm x adm var adm sbin nologin
lp x lp var spool lpd sbin nologin
sync x sync sbin bin sync
shutdown x shutdown sbin sbin shutdown
halt x halt sbin sbin halt
mail x mail var spool mail sbin nologin
uucp x uucp var spool uucp sbin nologin

2、统计

egrep -o "[a-zA-Z]+" awkfile.txt |sort|uniq –c
awk 'BEGIN{RS="()|\n"}{print NR,$0}' awkfile.txt |sort|uniq -c|sort –rn

企业按案例2:计算文件中重复的数量

 

1.3.1            记录小结:

  1. 大象放冰箱分几步?打开冰箱,把大象放进去,关闭冰箱门。
  2. 多使用,NR,NF,$数字,配合你调试你的awk命令
  3. NR number of record存放着每个记录的号(行号)读取新行时候会自动+1
  4. RS record separate是输入数据的记录的分隔符,简单理解就是可以指定每个记录的记录结尾标记
  5. (用RS替换\n)
  6. RS 作用就是表示一个记录的结束
  7. FS  表示着每个区域的结束

1.3.2            小结:

  1. $ 表示取区域,$1,$2 NF,$NF
  2. NF number of fileds 表示记录中的区域数量,$NF取最后一个区域
  3. FS(-F) filed separate区域分隔符,
  4. RS
  5. NR
  6. 选好合适的刀FS(***),RS,OFS,ORS
  7. $1,$3,$数字 选中你要处理的区域
  8. 分隔符==》结束表示
  9. 记录与区域,你就对我们所谓的行与列,有了新的认识。

用于第二行或第五行

[root@cobbler6 files]# awk  'NR==2||NR==5{print $1,$3}' awkfile.txt 
bin bin
lp lp

FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;
ARGC: awk命令的参数的个数;
FILENAME: awk命令所处理的文件的名称;
ENVIRON:当前shell环境变量及其值的关联数组;

1.4  正则表达式

[root@cobbler6 files]# awk -F "/" '$(NF-1)~/^bin/{print NF,$0,$3}' /etc/passwd

4 root:x:0:0:root:/root:/bin/bash bin
4 sync:x:5:0:sync:/sbin:/bin/sync bin
5 asdfghg:x:503:503::/home/asdfghg:/bin/bash asdfghg:
5 chujiyw001:x:809:809::/home/chujiyw001:/bin/bash chujiyw001:
5 chujiyw002:x:810:810::/home/chujiyw002:/bin/bash chujiyw002:
5 chujiyw003:x:811:811::/home/chujiyw003:/bin/bash chujiyw003:
5 ywsenior001:x:812:812::/home/ywsenior001:/bin/bash ywsenior001:
5 ywmanager001:x:813:813::/home/ywmanager001:/bin/bash ywmanager001:
5 chujikf001:x:814:814::/home/chujikf001:/bin/bash chujikf001:
5 chujikf002:x:815:815::/home/chujikf002:/bin/bash chujikf002:
5 kfsenior001:x:816:816::/home/kfsenior001:/bin/bash kfsenior001:
5 kfmanager001:x:817:817::/home/kfmanager001:/bin/bash kfmanager001:
5 jiak001:x:818:818::/home/jiak001:/bin/bash jiak001:
5 jiak002:x:819:819::/home/jiak002:/bin/bash jiak002:
5 chjidba001:x:820:820::/home/chjidba001:/bin/bash chjidba001:
5 chjidba002:x:821:821::/home/chjidba002:/bin/bash chjidba002:
5 chjidba003:x:822:822::/home/chjidba003:/bin/bash chjidba003:
5 dbasenior001:x:823:823::/home/dbasenior001:/bin/bash dbasenior001:
5 chjidwg001:x:824:824::/home/chjidwg001:/bin/bash chjidwg001:
5 chjidwg002:x:825:825::/home/chjidwg002:/bin/bash chjidwg002:
5 wgsenior001:x:826:826::/home/wgsenior001:/bin/bash wgsenior001:
[root@cobbler6 files]# awk -F "/" '$(NF-1)~/^bin/{print NF,$3}' /etc/passwd 4 bin 4 bin 5 asdfghg: 5 chujiyw001: 5 chujiyw002: 5 chujiyw003: 5 ywsenior001: 5 ywmanager001: 5 chujikf001: 5 chujikf002: 5 kfsenior001: 5 kfmanager001: 5 jiak001: 5 jiak002: 5 chjidba001: 5 chjidba002: 5 chjidba003: 5 dbasenior001: 5 chjidwg001: 5 chjidwg002: 5 wgsenior001: [root@cobbler6 files]# awk -F "/" '$(NF-1)~/^bin/{print NF,$0,$3}' /etc/passwd 4 root:x:0:0:root:/root:/bin/bash bin 4 sync:x:5:0:sync:/sbin:/bin/sync bin 5 asdfghg:x:503:503::/home/asdfghg:/bin/bash asdfghg: 5 chujiyw001:x:809:809::/home/chujiyw001:/bin/bash chujiyw001: 5 chujiyw002:x:810:810::/home/chujiyw002:/bin/bash chujiyw002: 5 chujiyw003:x:811:811::/home/chujiyw003:/bin/bash chujiyw003: 5 ywsenior001:x:812:812::/home/ywsenior001:/bin/bash ywsenior001: 5 ywmanager001:x:813:813::/home/ywmanager001:/bin/bash ywmanager001: 5 chujikf001:x:814:814::/home/chujikf001:/bin/bash chujikf001: 5 chujikf002:x:815:815::/home/chujikf002:/bin/bash chujikf002: 5 kfsenior001:x:816:816::/home/kfsenior001:/bin/bash kfsenior001: 5 kfmanager001:x:817:817::/home/kfmanager001:/bin/bash kfmanager001: 5 jiak001:x:818:818::/home/jiak001:/bin/bash jiak001: 5 jiak002:x:819:819::/home/jiak002:/bin/bash jiak002: 5 chjidba001:x:820:820::/home/chjidba001:/bin/bash chjidba001: 5 chjidba002:x:821:821::/home/chjidba002:/bin/bash chjidba002: 5 chjidba003:x:822:822::/home/chjidba003:/bin/bash chjidba003: 5 dbasenior001:x:823:823::/home/dbasenior001:/bin/bash dbasenior001: 5 chjidwg001:x:824:824::/home/chjidwg001:/bin/bash chjidwg001: 5 chjidwg002:x:825:825::/home/chjidwg002:/bin/bash chjidwg002: 5 wgsenior001:x:826:826::/home/wgsenior001:/bin/bash wgsenior001: [root@cobbler6 files]# awk -F ":" '$NF~/bash$/{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash asdfghg:x:503:503::/home/asdfghg:/bin/bash chujiyw001:x:809:809::/home/chujiyw001:/bin/bash chujiyw002:x:810:810::/home/chujiyw002:/bin/bash chujiyw003:x:811:811::/home/chujiyw003:/bin/bash ywsenior001:x:812:812::/home/ywsenior001:/bin/bash ywmanager001:x:813:813::/home/ywmanager001:/bin/bash chujikf001:x:814:814::/home/chujikf001:/bin/bash chujikf002:x:815:815::/home/chujikf002:/bin/bash kfsenior001:x:816:816::/home/kfsenior001:/bin/bash kfmanager001:x:817:817::/home/kfmanager001:/bin/bash jiak001:x:818:818::/home/jiak001:/bin/bash jiak002:x:819:819::/home/jiak002:/bin/bash chjidba001:x:820:820::/home/chjidba001:/bin/bash chjidba002:x:821:821::/home/chjidba002:/bin/bash chjidba003:x:822:822::/home/chjidba003:/bin/bash dbasenior001:x:823:823::/home/dbasenior001:/bin/bash chjidwg001:x:824:824::/home/chjidwg001:/bin/bash chjidwg002:x:825:825::/home/chjidwg002:/bin/bash wgsenior001:x:826:826::/home/wgsenior001:/bin/bas [root@cobbler6 files]# awk -F "/" '$NF~/^bash$/{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash asdfghg:x:503:503::/home/asdfghg:/bin/bash chujiyw001:x:809:809::/home/chujiyw001:/bin/bash chujiyw002:x:810:810::/home/chujiyw002:/bin/bash chujiyw003:x:811:811::/home/chujiyw003:/bin/bash ywsenior001:x:812:812::/home/ywsenior001:/bin/bash ywmanager001:x:813:813::/home/ywmanager001:/bin/bash chujikf001:x:814:814::/home/chujikf001:/bin/bash chujikf002:x:815:815::/home/chujikf002:/bin/bash kfsenior001:x:816:816::/home/kfsenior001:/bin/bash kfmanager001:x:817:817::/home/kfmanager001:/bin/bash jiak001:x:818:818::/home/jiak001:/bin/bash jiak002:x:819:819::/home/jiak002:/bin/bash chjidba001:x:820:820::/home/chjidba001:/bin/bash chjidba002:x:821:821::/home/chjidba002:/bin/bash chjidba003:x:822:822::/home/chjidba003:/bin/bash dbasenior001:x:823:823::/home/dbasenior001:/bin/bash chjidwg001:x:824:824::/home/chjidwg001:/bin/bash chjidwg002:x:825:825::/home/chjidwg002:/bin/bash wgsenior001:x:826:826::/home/wgsenior001:/bin/bash

  

[root@cobbler6 files]# awk  'NR==2,NR==5{print $1,$3}' awkfile.txt   
bin bin
daemon daemon
adm adm
lp lp

1.4.1            正则表达式小结:

1)        模式 ==》条件

2)        正则表达式

3)        条件表达式(NR>=2    NR==2),

4)        范围表达式  NR==2,NR==5)

5)        /正则表达式-开始/,/正则结束/

6)        $1~/正则表达式-开始/,$3~/正则结束/  行,记录。

7)        区域:FS刀分隔的,FS区域分隔符

8)        记录:RS刀分隔符,RS记录分隔符

9)    FS===>NF区域的数量

10)    RS===>NR记录号,随着记录的增加 NR自动+1

7.1 常见的模式类型:
1、Regexp: 正则表达式,格式为/regular expression/
2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符~(匹配)和!~(不匹配)。
3、Ranges: 指定的匹配范围,格式为pat1,pat2
4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
5、Empty(空模式):匹配任意输入行;

2  awk实战基础入门精讲

2.1  BENGIN模块和END模块

BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。

END:让用户在最后一条输入记录被读取之后发生的动作。

[root@cobbler6 files]# awk 'BEGIN{print "Hello world!"}'
Hello world!

[root@cobbler6 files]# awk 'BEGIN{RS="/"}{print NF $0}' awkfile2.txt
1root:x:0:0:root:
1root:
1bin
2bash
bin:x:1:1:bin

[root@cobbler6 files]# grep -c "^$"  /etc/services
16

[root@cobbler6 files]# awk '/^$/{a=a+1}END{print a}'  /etc/services
16

企业案例3:统计文件里面的空行数量

[root@cobbler6 ~]# awk '/^$/{a=a+1;print a}'  /etc/services 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

[root@cobbler6 ~]# awk '/^$/{a=a+1}END{print a}'  /etc/services
16

sed怎么调试,正则表达式调试

企业面试题4:awkfile2.txt里面 以:为分隔符,区域3大于15行,一共有多少行?

[root@cobbler6 files]# awk -F ":" '$3>15{a++}END{print a}' awkfile2.txt  
6

[root@cobbler6 files]# awk -F ":" '$3>15{a++;print a}END{print a}' awkfile2.txt
1
2
3
4
5
6
6


[root@cobbler6 files]# awk -F ":" 'BEGIN{print FS}'

2.1.1   总结:

 

2.2  预定义变量简介

 

2.3  awk数组

[root@cobbler6 files]# awk 'BEGIN{oldboy["a"]="oldgirl";oldboy["b"]="xiaoyu";oldloy["c"]="oldboy"

print oldboy["a"]
print oldboy["b"]
print oldloy["c"]

}'
oldgirl
xiaoyu
oldboy

awk数组的元素名(苹果名字)可以是字符串

字符串要使用双引号引起来""

[root@cobbler6 files]# awk -F "/" '{array[$3];print $3}' awkfile3.txt       
www.etiantian.org
www.etiantian.org
post.etiantian.org
mp3.etiantian.org
www.etiantian.org
post.etiantian.org

[root@cobbler6 files]# awk -F "/" '$3~/www.etiantian.org/' awkfile3.txt 
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://www.etiantian.org/3.html

[root@cobbler6 files]# awk -F "/"  '$3~/www.etiantian.org/{print $3}' awkfile3.txt   
www.etiantian.org
www.etiantian.org
www.etiantian.org

[root@cobbler6 files]# awk -F "/"  '$3~/www.etiantian.org/{array[e]}' awkfile3.txt        

[root@cobbler6 files]# awk -F "/"  '$3~/www.etiantian.org/{array["www.etiantian.org"]++;print array["www.etiantian.org"]}' awkfile3.txt
1
2
3

[root@cobbler6 files]# awk -F "/"  '{array[$3]++;print $3,array[$3]}' awkfile3.txt 
www.etiantian.org 1
www.etiantian.org 2
post.etiantian.org 1
mp3.etiantian.org 1
www.etiantian.org 3
post.etiantian.org 2

2.3.1            数组总结

  1. awk数组去重
  2. 选好分隔符 -F "/"
  3. 选好处理的区域,print $1,$3,$2
  4. array[$3]++
  5. 先处理,最后END模块输出
  6. 输出awk数组我们使用for(key in arry)
  7. =>for() 循环
  8. key in array手去筐里 抓苹果
  9. key就是苹果名字(框的的名字)
  10. array数组名(框的名字)
  11. 打印输出print  key,array[key]

3、控制语句:

8.1 if-else

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

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
awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

3.2 while

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

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

3.3 do-while

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

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

3.4 for

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

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

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

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

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

3.5 case

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

3.6 break 和 continue

常用于循环或case语句中

3.7 next

提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户:

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

4.4  awk英语

[root@cobbler6 files]# awk '{print NR,$0}' 20-30.txt 50-60.txt
1 20
2 21
3 22
4 23
5 24
6 25
7 26
8 27
9 28
10 29
11 30
12 50
13 51
14 52
15 53
16 54
17 55
18 56
19 57
20 58
21 59
22 60

[root@cobbler6 files]# awk '{print FNR,NR,$0}' 20-30.txt 50-60.txt
1 1 20
2 2 21
3 3 22
4 4 23
5 5 24
6 6 25
7 7 26
8 8 27
9 9 28
10 10 29
11 11 30
1 12 50
2 13 51
3 14 52
4 15 53
5 16 54
6 17 55
7 18 56
8 19 57
9 20 58
10 21 59
11 22 60

5、print

print的使用格式:

print item1, item2, ...

要点:

1、各项目之间使用逗号隔开,而输出时则以空白字符分隔;
2、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
3、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";

例子:

# awk 'BEGIN { print "line one\nline two\nline three" }'
awk -F: '{ print $1, $3 }' /etc/passwd

6、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: 显示宽度;
-: 左对齐;
+:显示数值符号;

例子:

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

7、输出重定向

print items > output-file
print items >> output-file
print items | command

特殊文件描述符:

/dev/stdin:标准输入
/dev/sdtout: 标准输出
/dev/stderr: 错误输出
/dev/fd/N: 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0;

例子:

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

7、awk的操作符:

7.1 算术操作符:

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

7.2 字符串操作符:

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

7.3 赋值操作符:

=
+=
-=
*=
/=
%=
^=
**=

++
--

需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,应以/[=]/替代;

7.4 布尔值

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

7.5 比较操作符:

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	True if the string x matches the regexp denoted by y. 
x !~ y	True if the string x does not match the regexp denoted by y. 
subscript in array	True if the array array has an element with the subscript subscript.

7.7 表达式间的逻辑关系符:

&&
||

7.8 条件表达式:

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

7.9 函数调用:

function_name (para1,para2)

生产常用功能总结

1、显示出某个范围内的内容

awk 'NR==20,NR==30' fliename

2、通过awk统计计算

awk '{sum+=$0}END{print sum}'

3、awk数组计算与去重

awk '{array[$1]++}END{for(key in array)print key,array[key]}' access.log

awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd
root Admin
bin Common User
daemon Common User
awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd root : Admin bin : Common User daemon : Common User awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

4、awk 实现给文件的每行内容之前加上行号

awk '{print NR,$0}'

5、显示第二到第六行

awk 'NR==2,NR==6 {print NR,$0}'

6、替换功能

awk '{gsub("/sbin/nologin","/bin/bash",$0);print $0}'

awk '{gsub("替换对象","替换成什么内容",那一列);print $0}'

注意:

  1. gsub与后面的括号之间不能有空格
  2. 替换对象、替换成什么内容以及那一列之间要用逗号隔开
  3. 替换队形的外面要有双引号或双斜线包裹起来,即"替换对象"或/替换对象/
  4. 替换成什么内容就只能用双引号括起来了,即"替换成什么内容"
  5. 最后一个是那一列,这个是可以省略的,省略的时候表示要替换整行的内容,相当于写上$0

八、常见awk用法

##提取两个文件第一列相同的行
awk -F',' 'NR==FNR{a[$1]=$0;next}NR>FNR{if($1 in a)print $0"\n"a[$1]}' 1.log 2.log

awk 'NR==FNR{a[$1]++}NR>FNR&&a[$1]>1' 111.txt 111.txt

awk 'a[$1]++==1' 

cat 111.txt | awk -F '[:|]' '{print $2}' > 111.txt

##awk 按某个位置的字符分隔的方法
awk -F ":" '{ for(i=1;i<=3;i++) printf("%s:",$i)}'
awk -F':' '{print $1 ":" $2 ":" $3; print $4}'
awk -F':' '{print $1 ":" $2 ":" $3; for(i=1;i<=3;i++)$i=""; print}'

##awk打印用户和密码
cat test.log  |awk -F '[ ]+' '{print $1 "   " $2}'

##排序显示重复项目
cat test.log |awk -F '[ ]+' '{print $1}'| sort | uniq -c | sort -nr

#awk -F '\t'来表示分隔符,比如
awk -F '\t' '{print $1}' file1.txt 

##多个空格分隔的方法
awk -F '[ ]+' '{print $9}'
ls -lh /etc/sysconfig/network-scripts/ifcfg-* | awk -F '[ ]+' '{print $9}'

##指定分隔符既可以为空格,又可以为冒号,那么处理将会变得简单。可以使用正则表达式来指定多个分隔符,格式为 -F'[空格:]+' 如下
awk -F'[ :]+' '{print $NF"\t"$(NF-2)}'  file1.txt 


1、awk '/101/'    file      显示文件file中包含101的匹配行。 
   awk '/101/,/105/'  file 
   awk '$1 == 5'    file 
   awk '$1 == "CT"'    file    注意必须带双引号 
   awk '$1 * $2 >100 '   file  
   awk '$2 >5 && $2<=15'  file


2、awk '{print NR,NF,$1,$NF,}' file     显示文件file的当前记录号、域数和每一行的第一个和最后一个域。 
   awk '/101/ {print $1,$2 + 10}' file       显示文件file的匹配行的第一、二个域加10。 
   awk '/101/ {print $1$2}'  file 
   awk '/101/ {print $1 $2}' file       显示文件file的匹配行的第一、二个域,但显示时域中间没有分隔符。


3、df | awk '$4>1000000 '         通过管道符获得输入,如:显示第4个域满足条件的行。


4、awk -F "|" '{print $1}'   file         按照新的分隔符“|”进行操作。 
   awk  'BEGIN { FS="[: \t|]" } 
   {print $1,$2,$3}'       file         通过设置输入分隔符(FS="[: \t|]")修改输入分隔符。 

   Sep="|" 
   awk -F $Sep '{print $1}'  file   按照环境变量Sep的值做为分隔符。    
   awk -F '[ :\t|]' '{print $1}' file   按照正则表达式的值做为分隔符,这里代表空格、:、TAB、|同时做为分隔符。 
   awk -F '[][]'    '{print $1}' file   按照正则表达式的值做为分隔符,这里代表[、]


5、awk -f awkfile    file         通过文件awkfile的内容依次进行控制。 
   cat awkfile 
/101/{print "\047 Hello! \047"}    --遇到匹配行以后打印 ' Hello! '.  \047代表单引号。 
{print $1,$2}                      --因为没有模式控制,打印每一行的前两个域。


6、awk '$1 ~ /101/ {print $1}' file         显示文件中第一个域匹配101的行(记录)。


7、awk   'BEGIN { OFS="%"} 
   {print $1,$2}'  file           通过设置输出分隔符(OFS="%")修改输出格式。


8、awk   'BEGIN { max=100 ;print "max=" max}             BEGIN 表示在处理任意行之前进行的操作。 
   {max=($1 >max ?$1:max); print $1,"Now max is "max}' file           取得文件第一个域的最大值。 
   (表达式1?表达式2:表达式3 相当于: 
   if (表达式1) 
       表达式2 
   else 
       表达式3 
   awk '{print ($1>4 ? "high "$1: "low "$1)}' file 


9、awk '$1 * $2 >100 {print $1}' file         显示文件中第一个域匹配101的行(记录)。


10、awk '{$1 == 'Chi' {$3 = 'China'; print}' file        找到匹配行后先将第3个域替换后再显示该行(记录)。 
    awk '{$7 %= 3; print $7}'  file           将第7域被3除,并将余数赋给第7域再打印。


11、awk '/tom/ {wage=$2+$3; printf wage}' file          找到匹配行后为变量wage赋值并打印该变量。


12、awk '/tom/ {count++;}  
         END {print "tom was found "count" times"}' file            END表示在所有输入行处理完后进行处理。


13、awk 'gsub(/\$/,"");gsub(/,/,""); cost+=$4; 
         END {print "The total is $" cost>"filename"}'    file             gsub函数用空串替换$和,再将结果输出到filename中。 
    1 2 3 $1,200.00 
    1 2 3 $2,300.00 
    1 2 3 $4,000.00 

    awk '{gsub(/\$/,"");gsub(/,/,""); 
    if ($4>1000&&$4<2000) c1+=$4; 
    else if ($4>2000&&$4<3000) c2+=$4; 
    else if ($4>3000&&$4<4000) c3+=$4; 
    else c4+=$4; } 
    END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file 
    通过if和else if完成条件语句 

    awk '{gsub(/\$/,"");gsub(/,/,""); 
    if ($4>3000&&$4<4000) exit; 
    else c4+=$4; } 
    END {printf  "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file 
    通过exit在某条件时退出,但是仍执行END操作。 
    awk '{gsub(/\$/,"");gsub(/,/,""); 
    if ($4>3000) next; 
    else c4+=$4; } 
    END {printf  "c4=[%d]\n",c4}"' file 
    通过next在某条件时跳过该行,对下一行执行操作。 


14、awk '{ print FILENAME,$0 }' file1 file2 file3>fileall              把file1、file2、file3的文件内容全部写到fileall中,格式为 
    打印文件并前置文件名。


15、awk ' $1!=previous { close(previous); previous=$1 }    
    {print substr($0,index($0," ") +1)>$1}' fileall           把合并后的文件重新分拆为3个文件。并与原文件一致。


16、awk 'BEGIN {"date"|getline d; print d}'         通过管道把date的执行结果送给getline,并赋给变量d,然后打印。 


17、awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}' 
    通过getline命令交互输入name,并显示出来。 
    awk 'BEGIN {FS=":"; while(getline< "/etc/passwd" >0) { if($1~"050[0-9]_") print $1}}' 
    打印/etc/passwd文件中用户名包含050x_的用户名。 

18、awk '{ i=1;while(i<NF) {print NF,$i;i++}}' file 通过while语句实现循环。 
    awk '{ for(i=1;i<NF;i++) {print NF,$i}}'   file 通过for语句实现循环。     
    type file|awk -F "/" ' 
    { for(i=1;i<NF;i++) 
    { if(i==NF-1) { printf "%s",$i } 
    else { printf "%s/",$i } }}'               显示一个文件的全路径。 
    用for和if显示日期 
    awk  'BEGIN { 
for(j=1;j<=12;j++) 
{ flag=0; 
  printf "\n%d月份\n",j; 
        for(i=1;i<=31;i++) 
        { 
        if (j==2&&i>28) flag=1; 
        if ((j==4||j==6||j==9||j==11)&&i>30) flag=1; 
        if (flag==0) {printf "%02d%02d ",j,i} 
        } 
} 
}'

  

posted @ 2018-02-20 16:12  活的潇洒80  阅读(553)  评论(0编辑  收藏  举报