第1章 linux系统三剑客

1.1 【grep/egrep】

[root@wangyoukun scripts]# grep IPADDR /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=10.0.0.200

[root@wangyoukun scripts]# grep "IPADDR|DNS1" /etc/sysconfig/network-scripts/ifcfg-eth0

[root@wangyoukun scripts]# egrep "IPADDR|DNS1" /etc/sysconfig/network-scripts/ifcfg-eth0

IPADDR=10.0.0.200

DNS1=223.5.5.5

 

[root@wangyoukun ~]# chkconfig |grep sshd 

sshd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

[root@wangyoukun ~]# chkconfig |grep "sshd|network"

[root@wangyoukun ~]# chkconfig |egrep "sshd|network"

network        0:off   1:off   2:on    3:on    4:on    5:on    6:off

sshd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

 

 

第2章 sed 的用法

2.1 命令作用:

sed是Stream Editor(字符流编辑器)的缩写,简称流编辑器。Sed命令是操作、过滤和转换文本内容的强大工具。常用功能有增(增加)删(删除)改(修改)查(查询),其中查询最常用的两大功能是过滤(过滤指定字符串),取行(取出指定行)。

  我们现在学习的sed版本是GNU开源版本的,我们的实验环境是Centos6.7系统,内核版本是2.6.32-642.el6.x86_64。

[root@oldboy35-edu ~]# cat /etc/redhat-release

CentOS release 6.8 (Final)

[root@oldboy35-edu ~]# uname -r

2.6.32-642.el6.x86_64

[root@oldboy35-edu ~]# sed –version  #查看sed软件版本

GNU sed version 4.2.1

…………省略若干行

语法格式

sed [options]  [sed-commands]  [input-file]

sed [选项]     [sed命令]      [输入文件]

2.2 命令执行流程:

sed软件从文件或管道中读取一行,处理一行,输出一行;然后在读取一行,处理一行,再输出一行····

参数选项说明:

options[选项]

                       解释说明(带为重点)

-n

取消默认的sed软件的输出,常与sed命令的p连用。※※※

-e

一行命令语句可以执行多条sed命令

-f

选项后面可以接sed脚本的文件名

-r

使用扩展正则表达式,默认情况sed只识别基本正则表达式。※※※

-i

直接修改文件内容,而不是输出终端。不用就不会修改文件内容和数据。※※※

[sed 命令]

                        解释说明(带为重点)

a

追加,在指定行后添加一行和多行文本。※※※

c

取代指定的行

d

删除指定的行。s/xxx/d※※※

D

删除模式空间的部分内容,直到遇到换行符\n结束操作,与多行模式相关

i

插入,在指定行前添加一行或多行文本。※※※

h

把模式空间的内容复制到保持空间。

H

把模式空间的内容追加到保持空间。

g

把保持空间的内容复制到模式空间。

G

把保持空间的内容追加到模式空间。

x

交换模式空间和保持空间的内容。

l

打印不可见的字符。

n

清空模式空间的内容并读入下一行。

N

不清空模式空间,并读取下一行数据并追加到模式空间。※※※

p

打印模式空间的内容,通常p会与选项-n一起使用。※※※

q

退出sed.

r

从指定文件读取数据。

s

取代,s#old#new#gè这里的g是s命令的替代标志,注意和g命令区分。※※※

w

另存,把模式空间的内容保存到文件中。

y

根据对应位置转换字符。

:lable

定义一个标签。

b lable

执行该标签后面的命令

t

如果前面的命令执行成功,那么就跳到t指定的标签处,继续往下执行后续命令

特殊符号

                  解释说明(带为重点)

$

匹配最后一行

对指定行意外的所有行应用命令。※※※

=

打印当前行号。※※※

~

表示从First行开始,以步长Step递增。

&

代表被替换的内容。

实行一行命令语句可以执行多条sed命令。Sed ‘2a A;B;C’※※※

{}

对单个地址或地址范围执行批量操作。

+

地址范围中用到的符号,做加法运算。

2.3 使用范例:

[root@oldboy35-edu ~]# cat >person.txt <<EOF     实验文本

> 101,oldboy,CEO

> 102,zhangyao,CTO

> 103,alex,COO

> 104,yy,CFO

> 105,feixue,CIO

> EOF

[root@oldboy35-edu ~]# cat person.txt 

101,oldboy,CEO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

2.3.1 增  往文件指定位置追加或插入文本 (单行增加)

[root@oldboy35-edu ~]# sed '2a 106,dandn,CSO' person.txt 将文本追加到第二行行后

101,oldboy,CEO

102,zhangyao,CTO

106,dandn,CSO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed '2i 106,dandan,CSO' person.txt 插入文本到第二行行前

101,oldboy,CEO

106,dandan,CSO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

往文件指定位置追加或插入文本 (多行增加)

[root@oldboy35-edu ~]# sed '2a 106,dandan,CSO\n107,bingbing,CCO' person.txt

101,oldboy,CEO   (这里通过\n可以把不同内容以回车方式多行增加到文本)

102,zhangyao,CTO

106,dandan,CSO

107,bingbing,CCO

103,alex,COO

104,yy,CFO

105,feixue,CIO

企业案例题1:优化ssh配置(一键完成增加若干参数)

  在我们学习Centos系统优化时,有一个优化点:更改ssh服务远程登录的配置。主要的操作是在ssh的配置文件/etc/ssh/sshd_config加入下面5行文本。

Port 52113

PermitRootLogin no

PermitEmptPassword no

UseDNS no

GSSAPIAuthentication no

当然我们可以使用vi/vim命令编辑这个文本,但这样就比较麻烦,现在想用一条命令增加5行文本到第13行前。注意:修改前别忘了备份配置文件:cp /etc/ssh/sshd_config{,.ori}  cp /etc/ssh/sshd_config.ori /etc/ssh/sshd_config(可进行恢复)

cp /etc/ssh/sshd_config{,.ori} 先对文件进行备份

sed -i “12a Port 52113\nPermitRoot no\nPermitEmtyPassswords no\nUseDNS no\nGSSAPTIAuthentication no" /etc/ssh/sshd_config(用sed命令多行追加功能就可以搞定)

命令说明:题目要求在第13行前插入,13i,当然也就是第12后,12a。最后插入5行内容,用“\n”就可以变成一行了。注意:“-i”这个选项能够实际的修改文件内容,在练习时可以去掉,防止改掉了配置文件。如果使用了“-i”,可以使用备份文件还原。生产环境修改配置文件那就需要-i选项了。

sed –n ’13,17p’ /etc/ssh/sshd_config 可查看是否添加成功

2.3.2 删   d 删除文本

[root@oldboy35-edu ~]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed '1~2d' person.txt (删除1、3、5奇数行)

102,zhangyao,CTO

104,yy,CFO

[root@oldboy35-edu ~]# sed '2~2d' person.txt (删除2、4偶数行)

101,oldboy,CEO

103,alex,COO

105,feixue,CIO

企业案例2:打印文件内容但不包含oldboy

[root@oldboy35-edu ~]# sed '/oldboy/d' person.txt (删除oldboy这一行)

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed '/oldboy/!d' person.txt (删除非oldboy这一行)

101,oldboy,CEO

[root@oldboy35-edu ~]# sed '2,3d' person.txt (删除2、3行)

101,oldboy,CEO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed '2,3!d' person.txt (不删除2、3行)

102,zhangyao,CTO

103,alex,COO

2.3.3 改   按行替换   C用新行取代旧行    c即change

[root@oldboy35-edu ~]# sed '2c 106,dandan.CSO' person.txt

101,oldboy,CEO

106,dandan.CSO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu-35 ~]# sed -i  's#zhangyao#dandan#g' person.txt(替换文本)

[root@oldboyedu-35 ~]# cat person.txt

101,oldboy,CEO

102,dandan,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu-35 ~]# sed -i  's#dandan#zhangyao#g' person.txt

[root@oldboyedu-35 ~]# cat person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

企业案例3:指定行进行修改

[root@oldboy35-edu ~]# sed '3s#0#9#g' person.txt

101,oldboy,CEO

102,zhangyao,CTO

193,alex,COO  (只将第三行0换成9)

104,yy,CFO

105,feixue,CIO

双引号把变量解析出来,单引号所见即所得,反引号则跟命令搭配使用

[root@oldboy35-edu ~]# sed 's#oldboy#$LANG#' person.txt

101,$LANG,CEO

102,ZHANGYAO,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed "s#oldboy#$LANG#" person.txt

101,en_US.UTF-8,CEO

102,ZHANGYAO,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

 

分组替换:     \(\)和\1

[root@oldboy35-edu ~]# echo "I am oldboy teacher."|sed -r 's#^.*am (.*) t.*$#\1#g'

oldboy

[root@oldboy35-edu ~]# echo "I am oldboy teacher."|sed  's#^.*am \([a-z].*\) t.*$#\1#g'

Oldboy

[root@oldboy35-edu ~]# echo "I am oldboy teacher."|sed -r 's#I (.*)(.*) tea.*$#\1\2#g'

am oldboy

取IP方案实例:

[root@oldboy35-edu ~]# ifconfig eth0|sed -rn '2s#^.*dr:(.*) Bc.*$#\1#gp'

192.168.56.128

企业案例4:系统开机自启动优化

[root@oldboy35-edu ~]# chkconfig|egrep -v "sshd|network|rsyslog|crond|sysstat"|awk '{print $1}'|sed -r 's#(.*)#chkconfig \1 off#g'|bash  或sed ‘s#.*#chkconfig & off#g’    (bash可以换成在g后加e)

[root@oldboy35-edu ~]# chkconfig|egrep -v "sshd|network|rsyslog|crond|sysstat"|awk '{print "chkconfig",$1,"off"}'|bash

[root@oldboy35-edu ~]# chkconfig |awk '!/sshd|network|rsyslog|sysstat/ {print "chkconfig",$1,"off"}'|bash

grep –ve “sshd|network|rsyslog|crond|sysstat”将我们保留的启动项取反排除。

awk '{print $1}' 使用awk把开机启动项名称取出来。

sed -r 's#(.*)#chkconfig \1 off#g'拼凑命令,“\1”代表前面^(.*)匹配的内容即开机启动的项目名称。

特殊符号&代表被替换的内容

&在适合的场景使用特别方便,用特殊符号“&”与分组替换一起使用,进行对比。

[root@oldboy35-edu ~]# cat person.txt

101,oldboy,CEO

102,ZHANGYAO,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed -r 's#(.*),(.*),(.*)#&----------- \1 \2 \3#' person.txt

101,oldboy,CEO----------- 101 oldboy CEO

102,ZHANGYAO,CTO----------- 102 ZHANGYAO CTO

103,alex,COO----------- 103 alex COO

104,yy,CFO----------- 104 yy CFO

105,feixue,CIO----------- 105 feixue CIO

这里将分组替换和&符号放在一起对比。命令中的分组替换使用了3个小括号,每个小括号分别代表每一行以逗号作为分隔符的每一列。上面的&符即代表每一行,即模型中’s#▆#▲#g’的▆。

企业案例5:批量重命名文件

当前目录下有文件如下所示:

[root@oldboy35-edu test]# ls

stu_102999_1_finished.jpg  stu_102999_3_finished.jpg  stu_102999_5_finished.jpg

stu_102999_2_finished.jpg  stu_102999_4_finished.jpg

要求用sed命令重命名,效果为:

stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg  stu_102999_5.jpg

用sed –r ‘s###g’

[root@oldboy35-edu test]# ls *jpg|sed -r 's#(.*)_finished(.*)#mv & \1\2 #g'|bash

[root@oldboy35-edu test]# ls *jpg

stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg  stu_102999_5.jpg

rename重命名

[root@oldboy35-edu test]# ls *jpg

stu_102999_1.jpg  stu_102999_2.jpg  stu_102999_3.jpg  stu_102999_4.jpg  stu_102999_5.jpg

[root@oldboy35-edu test]# rename jpg JPG *

[root@oldboy35-edu test]# ls

stu_102999_1.JPG  stu_102999_2.JPG  stu_102999_3.JPG  stu_102999_4.JPG  stu_102999_5.JPG  test.txt

[root@oldboy35-edu test]# rename  .JPG -`date +%F`.JPG  *

[root@oldboy35-edu test]# ls

stu_102999_1-2017-04-14.JPG  stu_102999_3-2017-04-14.JPG  stu_102999_5-2017-04-14.JPG

stu_102999_2-2017-04-14.JPG  stu_102999_4-2017-04-14.JPG

修改文件

[root@oldboy35-edu ~]# sed -i.ori 's#ZHANGYAO#MB#' person.txt

[root@oldboy35-edu ~]# cat person.txt

101,oldboy,CEO

102,MB,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# cat person.txt.ori

101,oldboy,CEO

102,ZHANGYAO,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

命令说明:使用person.txt.ori还原文件

[root@oldboy35-edu ~]# sed 'w opt.txt' person.txt

101,oldboy,CEO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# cat opt.txt

101,oldboy,CEO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

命令w可以把当前模式空间的内容保存到文件中。选项-i是直接修改源文件。默认情况下模式空间的内容每次都会打印到标准输出(屏幕),如果要把输出内容保存到文件同时不显示屏幕上,还需要使用-n选项取消默认输出

 

 

2.3.4 查    p

“p”:输出指定内容,但默认会输出2次匹配的结果,因此使用-n选项取消默认输出,记忆方法:p 即print,意思是打印。

[root@oldboy35-edu ~]# sed 'p' person.txt

101,oldboy,CEO

101,oldboy,CEO

102,zhangyao,CTO

102,zhangyao,CTO

103,alex,COO

103,alex,COO

104,yy,CFO

104,yy,CFO

105,feixue,CIO

105,feixue,CIO

[root@oldboy35-edu ~]# sed -n 'p' person.txt 取消默认输出

101,oldboy,CEO

102,zhangyao,CTO

103,alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboy35-edu ~]# sed -n '2p' person.txt 显示第二行

102,ZHANGYAO,CTO

[root@oldboy35-edu ~]# sed -n '/oldboy/p' person.txt

101,oldboy,CEO

过滤多个字符

[root@oldboy35-edu ~]# sed -rn '/oldboy|yy/p' person.txt

101,oldboy,CEO

104,yy,CFO

命令说明:使用扩展正则“|”,为了不使用转义符号“\”,因此使用-r选项开启扩展正则表达式模式。

2.4 sed软件替换命令详解

sed ‘[address-range|pattern-range] s#original-string#replacement-string#[substitute-flags]’ [input file]

sed’[地址范围|模式范围]s#[被替换的字符串]#[替换后的字符串]#[替换的标志]’[输入文件]

[root@oldboy35-edu ~]# cat person.txt

101,oldboy,CEO

102,MB,CTO

103,Alex,COO

104,yy,CFO

105,feixue,CIO

[root@oldboyedu-35 ~]# sed 's#alex#NB#i' person.txt 使用i来忽略大小写

101,oldboy,CEO

102,zhangyao,CTO

103,NB,COO

104,yy,CFO

105,feixue,CIO

Ms# # #Ng的使用

●Msà对第M行处理,无g替换标志,只处理第一处匹配,有g替换标志则对第M行全部替换。

●Ngà对每一行,从第N行开始替换。

●Ms、Ng合用表示只对第M行从第N行匹配开始替换

[root@oldboy35-edu ~]# sed '2s#1#0#g' a.txt  有g替换标志则对第2行全部替换

1 1 1 1 1

0 0 0 0 0

1 1 1 1 1

1 1 1 1 1

1 1 1 1 1

[root@oldboy35-edu ~]# sed '3s#1#0#2' a.txt对第三行的第二个字符进行替换

1 1 1 1 1

1 1 1 1 1

1 0 1 1 1

1 1 1 1 1

1 1 1 1 1

打印标志:p

打印标志p,当替换操作完成后,打印替换后的行,与选项-n连用。这里的p是附属于sed命令s的,是一个标志

[root@oldboy35-edu ~]# sed -n 's#oldboy#NB#p' person.txt

101,NB,CEO

执行命令标志:e

执行命令标志e,可以将模式空间中的任何内容当做shell命令执行,并把命令执行的结果返回到模式空间。

[root@oldboy35-edu ~]# cat file.txt

/etc/passwd

/etc/my.cnf

[root@oldboy35-edu ~]# sed 's#^#ls -lh #e' file.txt

-rw-r--r--. 1 root root 2.2K Apr 10 09:14 /etc/passwd

-rw-r--r--. 1 root root 251 May 11  2016 /etc/my.cnf

创建一个测试文本,注意ls –lh 后面要有一个空格,就能够执行命令

[root@oldboy35-edu ~]# sed 's#^#ls -lh #p' file.txt

ls -lh /etc/passwd

ls -lh /etc/passwd

ls -lh /etc/my.cnf

ls -lh /etc/my.cnf

6.特殊符号=获取行号

如何获取一个文件的行号?

[root@oldboy35-edu ~]# sed "=" person.txt

1

101,oldboy,CEO

2

102,MB,CTO

3

103,Alex,COO

4

104,yy,CFO

5

105,feixue,CIO

用cat –n或nl或less –N都能查看文件的行号。

命令说明:使用特殊符号“=”就可以读取文件的行号,这是特殊用法,记住即可;行号和行不在一行。

[root@oldboy35-edu ~]# sed '1,3=' person.txt

1

101,oldboy,CEO

2

102,MB,CTO

3

103,Alex,COO

104,yy,CFO

105,feixue,CIO

读取第1~3行包含第3行的行号

改进方法

[root@oldboy35-edu ~]# sed '=' person.txt |sed 'N;s#\n# #'

1 101,oldboy,CEO

2 102,MB,CTO

3 103,Alex,COO

4 104,yy,CFO

5 105,feixue,CIO

命令说明:sed命令N读取下一行数据并附加到模式空间。

7.一条sed语句执行多条命令

面试题:用一条sed语句实现删除文件的第三行到末尾的数据,并把剩余喊得数字10替换为01.

使用选项-e,每个-e选项后可接一个命令。

[root@oldboy35-edu ~]# sed -e '3,$d' -e 's#10#01#' person.txt

011,oldboy,CEO

012,MB,CTO

命令说明:第一个-e选项后接‘3,$d’表示删除文件的第3行到末尾的数据,第二个-e选项后接‘s#10#01#表示把数字10换成01.

[root@oldboyedu-35 ~]# sed '3a 123;4a 456' person.txt在第3行行为插入123;4a 456

101,oldboy,CEO

102,zhangyao,CTO

103,Alex,COO

123;4a 456

104,yy,CFO

105,feixue,CIO

[root@oldboyedu-35 ~]# sed '3d;4a 456' person.txt删除第3行,在第四行行为插入456

101,oldboy,CEO

102,zhangyao,CTO

104,yy,CFO

456

105,feixue,CIO

企业案例6:一个文件100行,把5,35,70行单独拿出来

[root@oldboy35-edu ~]# sed -n '5p;35p;70p' /etc/services

# IANA services version: last updated 2009-11-10

qotd            17/tcp          quote

whois++         63/udp

命令说明:这里用分号隔开即可全部显示出来。

8.保持空间和模式空间

模式空间操作命令n

   命令n的作用:清空当前模式空间的内容,然后从输入文件中读取下一行。如果在命令执行过程中遇到n,那么它会改变正常的执行流程(读取数据、执行命令、打印输出、重复循环)。

   Sed调试工具sedsed:sedsed软件是一个很棒的调试sed语句的工具,sedsed软件会详细显示sed执行流程。sedsed软件是时下最流行的语言python写的,简单易用。sedsed软件最新版本是1.0版本,这个版本支持所有安装python2版本的系统平台,软件官网:http://aurelio.net/projects/sedsed/.

sedsed语法:sedsed取代sed软件的位置。

常用选项:

选项

                     解释说明

-d

开启调试模式

--hide

隐藏一些调试信息,选项有:PATT,HOLD,COMM。

PATT是pattern模式的缩写,即模式空间

HOLD是保持空间

COMM是command的缩写,即sed命令

-n

取消默认输出

$

正则里表示文件的结尾。如果在文件的开头是$,则表示空行。

[root@oldboy35-edu ~]# sedsed -d -n --hide=HOLD 'p;n' person.t1t

PATT:101,oldboy,CEO$

COMM:p

101,oldboy,CEO

PATT:101,oldboy,CEO$

COMM:n

PATT:102,MB,CTO$

PATT:103,alex,COO$

COMM:p

103,alex,COO

PATT:103,alex,COO$

COMM:n

PATT:104,yy,CFO$

PATT:105,feixue,CIO$

COMM:p

105,feixue,CIO

PATT:105,feixue,CIO$

COMM:n

[root@oldboy35-edu ~]# sedsed -d -n --hide=HOLD 'p;n;p' person.t1t

PATT:101,oldboy,CEO$

COMM:p

101,oldboy,CEO

PATT:101,oldboy,CEO$

COMM:n

PATT:102,MB,CTO$

COMM:p

102,MB,CTO

PATT:102,MB,CTO$

PATT:103,alex,COO$

COMM:p

103,alex,COO

PATT:103,alex,COO$

COMM:n

PATT:104,yy,CFO$

COMM:p

104,yy,CFO

PATT:104,yy,CFO$

PATT:105,feixue,CIO$

COMM:p

105,feixue,CIO

PATT:105,feixue,CIO$

COMM:n

命令N的作用:不会清空模式空间内容,并且从输入文件中读取下一行数据,追加到模式空间中,两行数据以换行符\n链接。

[root@oldboy35-edu ~]# sed '=' person.txt|sed "N;s#\n# #g"

1 101,oldboy,CEO

2 102,MB,CTO

3 103,Alex,COO

4 104,yy,CFO

5 105,feixue,CIO

sed '=' person.txt|sedsed --hide=HOLD -d  'N;s#\n# #'

 

 

 

第3章 awk的用法

3.1 awk在shell中使用场景

3.1.1 awk计算场景

[root@wangyoukun scripts]# vim awk.sh

#!/bin/bash

num1=$1

num2=$2

awk -va=$num1 -vb=$num2 'BEGIN{print a+b}'

awk -va=$num1 -vb=$num2 'BEGIN{print a-b}'

awk -va=$num1 -vb=$num2 'BEGIN{print a*b}'

awk -va=$num1 -vb=$num2 'BEGIN{print a/b}'

 

 

3.1.2 awk替换场景

[root@wangyoukun oldboy]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print}' reg.txt

Zhang Xiaoyu 390320151 $155$90$201 ##显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135

 

gsub(//,"",$NF)

gsub(/你要找的内容/,"替换成什么",在哪里列里面进行替换)

[root@oldboyedu45-lnb oldboy]# awk '{gsub(/:/,"$",$NF)}' reg.txt

 

 

3.1.3 awk取行场景

[root@wangyoukun test]# awk 'NR==1,NR==3' /etc/services

# /etc/services:

# $Id: services,v 1.48 2009/11/11 14:32:31 ovasik Exp $

#

[root@wangyoukun test]# awk 'NR==1,NR==3{print $0}' /etc/services

# /etc/services:

# $Id: services,v 1.48 2009/11/11 14:32:31 ovasik Exp $

#

3.1.4 awk取列场景

[root@wangyoukun test]# ls -lrt |awk '{print $NF}'

 

3.1.5 awk查找场景

[root@wangyoukun Get_Max_value]# cat get_max.sh

#!/bin/bash

get_max(){

A=

B=

while read line

do

    B=$line

    C=$(awk -v a=$A -v b=$B 'BEGIN{print(a>b)?"0":"1"}')

    if [ $C -eq 1 ];then

      A=$B

    fi

done <./a.txt

echo 'Max:'$A

}

get_min(){

A=1

B=

while read line

do

    B=$line

    C=$(awk -v a=$A -v b=$B 'BEGIN{print(a>b)?"0":"1"}')

    if [ $C -eq 0 ];then

      A=$B

    fi

done <./a.txt

echo 'Min:'$A

}

main(){

get_max

#sleep 5

get_min

}

main $@

3.1.6 统计行号

awk '{print NR, $0}' passwd.txt ###显示行号

 

3.1.7 awk统计场景

3.1.7.1  统计次数场景

[root@wangyoukun test]# awk '{i++}END{print i}' /etc/services

10774

[root@wangyoukun test]# awk '{i=i+1}END{print i}' /etc/services

10774

[root@wangyoukun test]# wc -l /etc/services

10774 /etc/services

 

 

3.1.7.2  分类统计总和场景

  • 统计总和场景(单场景情况)

[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum}' access.log

2478496663   

 

  • 分类统计总和场景(多场合情况) 结合数组实现

[root@wangyoukun oldboy]# cat html.txt|awk -F "[./]+" '{h[$2]++}END{for(pol in h)print pol,h[pol]}'

www 3                                      ##分类统计 www post mp3 ......出现的次数              

mp3 1

post 2 

 

3.1.8 BEGIN和END模块

[root@wangyoukun Get_Max_value]# seq 10 |awk 'BEGIN{print "start"}{print $0}END{print "end"}'

start

1

2

3

4

5

6

7

8

9

10

end

 

 

 

3.2 awk主要可以干什么

1.取列 取行 计算 统计 查找 变量

2.统计

3.3 awk结构

awk  -F "[ :]+"    'NR==2{print $4}'

awk   参数         '模式{动作}'

 

[root@wangyoukun ~]# ifconfig eth0

eth0      Link encap:Ethernet  HWaddr 00:0C:29:00:16:B4 

          inet addr:10.0.0.200  Bcast:10.0.0.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:fe00:16b4/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:58949 errors:0 dropped:0 overruns:0 frame:0

          TX packets:80971 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:11036576 (10.5 MiB)  TX bytes:80575920 (76.8 MiB)

[root@wangyoukun ~]# ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}'

10.0.0.200

3.4 awk的执行过程

行   列

awk –F ":"=======> awk -vFS=":"

awk -F ":" '{print $1","$3}' passwd.txt

awk -vFS=":" '{print $1,$3}' passwd.txt

[root@wangyoukun ~]# cat passwd.txt |awk -vFS=":" '{print $1","$3}'

root,0

bin,1

daemon,2

adm,3

lp,4

sync,5

shutdown,6

halt,7

mail,8

 

awk -F: -vOFS=":" =====> awk -vFs:  -vOFS=":"

[root@wangyoukun ~]# cat passwd.txt|awk -F: -vOFS=":" '{print $NF,$2,$3,$4,$5,$6,$1}'

/bin/bash:x:0:0:root:/root:root

/sbin/nologin:x:1:1:bin:/bin:bin

/sbin/nologin:x:2:2:daemon:/sbin:daemon

/sbin/nologin:x:3:4:adm:/var/adm:adm

/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp

/bin/sync:x:5:0:sync:/sbin:sync

/sbin/shutdown:x:6:0:shutdown:/sbin:shutdown

/sbin/halt:x:7:0:halt:/sbin:halt

/sbin/nologin:x:8:12:mail:/var/spool/mail:mail

 

[root@wangyoukun ~]# cat passwd.txt|awk -F: -vOFS=":" '{tmp=$1;$1=$NF;$NF=tmp;print}'

/bin/bash:x:0:0:root:/root:root                  ###条件tmp 是空杯,$1 是可乐,$NF 是雪碧

/sbin/nologin:x:1:1:bin:/bin:bin                 ###问题:如何调换可乐与雪碧的杯子?

/sbin/nologin:x:2:2:daemon:/sbin:daemon          ###解答:有一个空杯,可以实现互换液体

/sbin/nologin:x:3:4:adm:/var/adm:adm             ###过程:把可乐放进空杯,再将雪碧放进盛放可乐的空杯

/sbin/nologin:x:4:7:lp:/var/spool/lpd:lp         ###子中,最后把盛放可乐的杯子放进盛放雪碧的杯子

/bin/sync:x:5:0:sync:/sbin:sync

/sbin/shutdown:x:6:0:shutdown:/sbin:shutdown

/sbin/halt:x:7:0:halt:/sbin:halt

/sbin/nologin:x:8:12:mail:/var/spool/mail:mail

3.5 通过awk找到你要的内容-模式

    正则表达式作为模式

    比较表达式作为模式 NR>10

    范围模式

    特殊模式BEGIN和END

3.5.1 正则表达式作为模式

#第3列 包含 数字3-5的行显示出来

[root@wangyoukun ~]# cat passwd.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

[root@wangyoukun ~]# awk -F":" '$3~/[3-5]/' passwd.txt   #第3列 包含 数字3-5的行显示出来

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

 

 

#第5列 包含 字母的行显示出来

[root@oldboyedu45-lnb oldboy]# awk -F: '$5~/[a-z]/' passwd.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

 

创建环境

cat >>/oldboy/reg.txt<<EOF

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

Meng  Feixue    80042789   :250:60:50

Wu    Waiwai    70271111   :250:80:75

Liu   Bingbing  41117483   :250:100:175

Wang  Xiaoai    3515064655 :50:95:135

Zi    Gege      1986787350 :250:168:200

Li    Youjiu    918391635  :175:75:300

Lao   Nanhai    918391635  :250:100:175

EOF

 

姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

[root@wangyoukun oldboy]# cat reg.txt

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

Meng  Feixue    80042789   :250:60:50

Wu    Waiwai    70271111   :250:80:75

Liu   Bingbing  41117483   :250:100:175

Wang  Xiaoai    3515064655 :50:95:135

Zi    Gege      1986787350 :250:168:200

Li    Youjiu    918391635  :175:75:300

Lao   Nanhai    918391635  :250:100:175

 

[root@wangyoukun oldboy]# awk -F "[ :]+" '$1~/Zhang/{print $5,$1,$2}' reg.txt

100 Zhang Dandan                         ##姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

90 Zhang Xiaoyu                          ##第二次捐款是$5

[root@oldboyedu45-lnb oldboy]# awk -F "[ :]+" '$1~/Zhang/{print $1,$2,$(NF-1)}'  reg.txt

Zhang Dandan 100                         ##姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

Zhang Xiaoyu 90                          ##第二次捐款是最后一列的前一列,记住括号要括起来

 

[root@oldboyedu45-lnb oldboy]# awk '$1~/Zhang/'  reg.txt ##姓氏是Zhang的行

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

 

awk 取第一行 NR==1 ==>  NR==1{print $0} ==>  NR==1{print }

[root@oldboyedu45-lnb oldboy]# awk 'NR==1' reg.txt

Zhang Dandan    41117397   :250:100:175

[root@oldboyedu45-lnb oldboy]# awk 'NR==1{print $0}' reg.txt

Zhang Dandan    41117397   :250:100:175

[root@oldboyedu45-lnb oldboy]# awk 'NR==1{print }' reg.txt

Zhang Dandan    41117397   :250:100:175

 

显示所有ID号码最后一位数字是1或5的人的全名

[root@oldboyedu45-lnb oldboy]# awk '$3~/[15]$/' reg.txt

Zhang Xiaoyu    390320151  :155:90:201  ##显示所有ID号码最后一位数字是1或5的人的行

Wu    Waiwai    70271111   :250:80:75

Wang  Xiaoai    3515064655 :50:95:135

Li    Youjiu    918391635  :175:75:300

Lao   Nanhai    918391635  :250:100:175

[root@oldboyedu45-lnb oldboy]# awk '$3~/[15]$/{print $1,$2}' reg.txt

Zhang Xiaoyu                            ##显示所有ID号码最后一位数字是1或5的人的全名

Wu Waiwai

Wang Xiaoai

Li Youjiu

Lao Nanhai

 

 

[root@wangyoukun oldboy]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print}' reg.txt

Zhang Xiaoyu 390320151 $155$90$201 ##显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135

3.6 awk 替换

gsub(//,"",$NF)

gsub(/你要找的内容/,"替换成什么",在哪里列里面进行替换)

[root@oldboyedu45-lnb oldboy]# awk '{gsub(/:/,"$",$NF)}' reg.txt

[root@oldboyedu45-lnb oldboy]# awk '{gsub(/:/,"$",$NF); print}' reg.txt

Zhang Dandan 41117397 $250$100$175

Zhang Xiaoyu 390320151 $155$90$201

Meng Feixue 80042789 $250$60$50

Wu Waiwai 70271111 $250$80$75

Liu Bingbing 41117483 $250$100$175

Wang Xiaoai 3515064655 $50$95$135

Zi Gege 1986787350 $250$168$200

Li Youjiu 918391635 $175$75$300

Lao Nanhai 918391635 $250$100$175

 

 

显示所有人的全名,以姓,名的格式显示,如Meng,Feixue

[root@oldboyedu45-lnb oldboy]# awk -vOFS=, '{print $1,$2}' reg.txt

Zhang,Dandan

Zhang,Xiaoyu

Meng,Feixue

Wu,Waiwai

Liu,Bingbing

Wang,Xiaoai

Zi,Gege

Li,Youjiu

Lao,Nanhai

 

 

 

101.226.61.184 - - [22/Nov/2015:11:02:00 +0800] "GET /mobile/theme/oldboy/common/images/arrow-down2.png HTTP/1.1" 200 24662 "http://m.oldboyedu.com.cn/mobile/theme/oldboy/home/index.html" "Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; HUAWEI CRR-UL00 Build/HUAWEICRR-UL00) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025478 Mobile Safari/533.1 MicroMessenger/6.3.7.51_rbb7fa12.660 NetType/3gnet Language/zh_CN"

 

3.7      企业案例 :统计/etc/services文件里面的空行数量

#i=i+1  ===>  i++  计算总次数

[root@oldboyedu45-lnb oldboy]# awk '/^$/{i++}END{print i}'  /etc/services

16                              ##统计/etc/services文件里面的空行数量

[root@oldboyedu45-lnb oldboy]# awk '/^$/{i=i+1 }END{print i}'  /etc/services

16

 

[root@wangyoukun oldboy]# seq 10|awk '{i=i+$1}END{print i}'

55                              ##计算从1加到10的结果

 

# 计算access.log中 一共使用了多少流量?

sum+=$10 ====> sum=sum+$10

[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum}' access.log

2478496663                   ##计算access.log中 一共使用了多少流量?

[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum/1024^3}' access.log

2.30828                      ##计算access.log中 一共使用了多少流量?没有加单位

[root@wangyoukun ~]# awk '{sum=sum+$10}END{print sum/1024^3"G"}' access.log

2.30828G                     ##计算access.log中 一共使用了多少流量?单位是G

3.8 小结 awk

1.BEGIN{}  END{}√

2.awk统计-核心:先计算然后END{}显示结果

3.

i=i+1     ===  i++       计算总次数

i=i+$xx   ===  i+=$xxx   计算总和

 

[root@wangyoukun ~]# awk '{print NR, $0}' passwd.txt ###显示行号

1 root:x:0:0:root:/root:/bin/bash

2 bin:x:1:1:bin:/bin:/sbin/nologin

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

4 adm:x:3:4:adm:/var/adm:/sbin/nologin

5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6 sync:x:5:0:sync:/sbin:/bin/sync

7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

8 halt:x:7:0:halt:/sbin:/sbin/halt

9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

3.9 awk数组

处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)

http://www.etiantian.org/index.html

http://www.etiantian.org/1.html

http://post.etiantian.org/index.html

http://mp3.etiantian.org/index.html

http://www.etiantian.org/3.html

http://post.etiantian.org/2.html

分类统计 www post mp3 ......出现的次数

[root@wangyoukun oldboy]# cat html.txt|awk -F "[./]+" '{h[$2]++}END{for(pol in h)print pol,h[pol]}'

www 3                                      ##分类统计 www post mp3 ......出现的次数              

mp3 1

post 2                                     #####套用公式比较方便

 

[root@oldboyedu45-lnb oldboy]# awk -F "[./]+" '$2~/www/{a++}$2~/post/{b++}$2~/mp3/{c++}END{print a,b,c}' url.txt                            ###这种情况只适合于小文件,种类较少的情况,不便于查看

3 2 1                                      ###不建议用这种方法,那么数组就产生了

 

[root@oldboyedu45-lnb oldboy]# awk 'BEGIN{h[110]="taotao";print h[110]}'

taotao

[root@oldboyedu45-lnb oldboy]# awk  -F "[/.]+"   '{h[$2]++;print "www",h["www"]}' url.txt

www 1

www 2

www 2

www 2

www 3

www 3

 

h[$2]++

[root@oldboyedu45-lnb oldboy]# awk  -F "[/.]+"   '{h[$2]++}END{print h["www"],h["mp3"],h["post"]}' url.txt

3 1 2

 

[root@oldboyedu45-lnb oldboy]# awk  -F "[/.]+"   '{h[$2]++}END{for(pol in h) print pol }' url.txt

www

mp3

post

[root@oldboyedu45-lnb oldboy]# awk  -F "[/.]+"   '{h[$2]++}END{for(pol in h) print pol,h[pol] }' url.txt

www 3

mp3 1

post 2

'{h[$2]++}END{for(pol in h)      print pol        h[pol] }'

                  变量         数组        元素名称,内容

                                           房间号码

 

统计access.log中每个ip的访问次数

 awk '{h[$1]++}END{for(pol in h) print pol,h[pol]}' access.log |sort -rnk2|head

 

[root@wangyoukun ~]# awk '{h[$1]++}END{for(pol in h) print pol,h[pol]}' access.log |head |sort -rnk2

101.226.125.119 569

180.154.137.177 516

101.226.125.118 437

180.158.118.17 347

101.226.125.115 284

14.152.68.38 162

140.206.89.150 130

101.226.125.116 127

117.12.191.55 106

110.75.248.79 1

 

 

3.10 awk 数组知识小结

3.10.1 特殊的模式BEGIN{}   END{}

BEGIN{} 模块在awk读取文件之前就执行

awk 'BEGIN{print "start"}  {print}' reg.txt

[root@wangyoukun oldboy]# awk 'BEGIN{print "start"} {print }' reg.txt

start

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

Meng  Feixue    80042789   :250:60:50

Wu    Waiwai    70271111   :250:80:75

Liu   Bingbing  41117483   :250:100:175

Wang  Xiaoai    3515064655 :50:95:135

Zi    Gege      1986787350 :250:168:200

Li    Youjiu    918391635  :175:75:300

Lao   Nanhai    918391635  :250:100:175

1)测试

2) 定义或修改awk内置变量

-vOFS=:  =====>  'BEGIN{OFS=:}'

END{}在awk读取完所有的文件的时候,再执行END模块,一般用来输出一个结果(累加,数组结果),

先计算,END{}显示最终结果

3.10.2 数组活学活用

awk  -F "[/.]+"   '{h[$2]++}END{for(pol in h) print pol,h[pol] }' url.txt

拿好菜刀(分隔符),找到要统计的列,计算结果

3.10.3 计算总次数     i=i+1     ===  i++ 

  awk '/^$/{i++}END{print i}'  /etc/services

##统计/etc/services文件里面的空行数量

3.10.4 计算总和      i=i+$xx   ===  i+=$xxx  

  awk '{sum=sum+$10}END{print sum}' access.log

  seq 10|awk '{i=i+$1}END{print i}'

3.11 练习题目

3.11.1 题目一(已解答)

#第1列    ip地址

#第7列    URL 网址

#第10列   文件的大小  流量大小

显示access.log中第7列中以.jpg或.png结尾的ip地址和URL

解答:awk '$7~/(.jpg)|(.png)$/{print $1,$7}' access.log

显示access.log中第10列中大于5000的ip地址和url

解答:awk '$10>5000{print $1,$7}' access.log

3.12 题目二 尚在研究中…...

1.分析谁在破解你的密码(每个ip破解的次数) secure-2016xxxx

2.分析每个用户被破解的次数

3.access.log 计算每个ip地址使用的流量

4.统计access.log显示每个ip地址的访问次数和每个ip地址使用的流量

 

第4章 用法举例

4.1 awk基础用法举例

[root@wangyoukun AWK_SED_GREP]# cat html.txt |awk -F '[:/]' 'BEGIN{print "start"}{h[$4]++}END{for(i in h)print h[i],i}'

start

1 mp3.etiantian.org

2 post.etiantian.org

3 www.etiantian.org

 

4.2 access访问日志 实战用法举例一

注释项:

#第1列    ip地址

#第7列    URL 网址

#第10列   文件的大小  流量大小

 

4.2.1 显示access.log中第7列中以.jpg或.png结尾的ip地址和URL

解答:awk '$7~/(.jpg)|(.png)$/{print $1,$7}' access.log

cat access.log  |awk '$7~/.jpg$|.png$/{h[$1]++}END{for(a in h)print h[a],a,$7}'|sort  -gr

[root@wangyoukun use_awk_2]# cat access.log  |awk '$7~/.jpg$|.png$/{h[$1]++}END{for(a in h)print h[a],a,$7}'|sort  -gr|head

778 114.83.184.139 /online/oldboyonline/images/forms/validatePass.png

732 112.64.171.98 /online/oldboyonline/images/forms/validatePass.png

722 58.220.223.62 /online/oldboyonline/images/forms/validatePass.png

573 117.136.66.10 /online/oldboyonline/images/forms/validatePass.png

446 116.216.30.47 /online/oldboyonline/images/forms/validatePass.png

383 223.104.5.197 /online/oldboyonline/images/forms/validatePass.png

383 116.216.0.60 /online/oldboyonline/images/forms/validatePass.png

301 223.104.5.202 /online/oldboyonline/images/forms/validatePass.png

289 114.111.166.22 /online/oldboyonline/images/forms/validatePass.png

269 114.141.164.180 /online/oldboyonline/images/forms/validatePass.png

4.2.2 显示access.log中第10列中大于5000的ip地址和url

解答:awk '$10>5000{print $1,$7}' access.log

cat access.log|awk '$10>5000{h[$1]++}{for(a in h)print h[a],a,$7}'  |sort -gr

 

4.2.3 access.log 计算每个ip地址使用的流量

cat access.log |awk '{h[$1]+=$10}END{for(a in h)print h[a],a}'|sort -gr |head

31362956 114.83.184.139

22431302 117.136.66.10

21466000 116.216.30.47

21464856 223.104.5.197

19145329 116.216.0.60

17219553 114.141.164.180

17121524 114.111.166.22

16911512 223.104.5.202

15969887 116.228.21.187

15255013 112.64.171.98

 

4.2.4 统计access.log显示每个ip地址的访问次数和每个ip地址使用的流量

每个ip地址访问次数

cat access.log |awk '{h[$1]++}END{for(a in h)print h[a],a}'|sort -gr |head

每个ip地址使用的流量

cat access.log |awk '{h[$1]+=$10}END{for(a in h)print h[a],a}'|sort -gr |head

posted on   开心的小土豆  阅读(99)  评论(0编辑  收藏  举报
努力加载评论中...



点击右上角即可分享
微信分享提示