shell脚本三剑客(grep,sed,awk)


1.grep详解及用法

( 1 )grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来),是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。抓取、过滤、筛选,找文件的内容。

Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。

linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

参数

说明

-v

反转查找、过滤

-n

显示行号

-i

忽略大小写

-E

=egrep

-a

在二进制中,以文本文件的方式搜索数据

-o

只输出文件中匹配到的信息

-c

统计匹配的行数

( 2 ) grep 常见用法

          - n 过滤并显示行号

     

 

 

         - v 排除某行

      

         - i 忽略大小写

       

           - c 统计匹配的行数

       

 

 

   小试牛刀: 用grep+cut 取网卡的IP

       

 

 

 2. 经过上面的小题让我们知道grep也不是万能的所以我们就需要运用到第二个文件处理工具 sed 。

( 1 )sed的详解及用法

 sed是一个很好的文件处理工具,本身是一个管道命令。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件匹配内容选取之后再输入到  屏幕,可以把只匹配到模式的内容输入到屏幕上。

 还可以对原文件内容行进行替换、删除、新增等特定工作改动,但是不会再屏幕上返回结果。

 ( 2 )sed 命令参数

参数

说明

- i

修改内容

- n

取消默认输出

- r

在脚本中支持扩展正则表达式

- e

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

- h

也就是--help 显示帮助 

( 2.1 ) sed标记参数(前面没有 - 的参数),也可以称之为编辑器

a∶	在定位行后新增内容, a 的后面可以接字符串,而这些字符串会在新的一行出现(当前行的下一行);
c∶	用新文本替换定位文本, c 的后面可以接字符串,这些字符串可以取代 n1,n2 之间的行;
d∶	删除定位行,因为是删除啊,所以 d 后面通常不接任何咚咚;
g∶	表示行内全面替换。 --global
i∶	在定位行前插入新内容, i 的后面可以接字符串,而这些字符串会在新的一行出现(当前行的上一行);
I∶	还是| 显示与八进制ACSII代码等价的控制符;
n∶	从另一个文件中读文本下一行,并从下一条命令而不是第一条命令开始对其的处理;
N∶	在数据流中添加下一行以创建用于处理的多行组;
p∶	列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作;
q∶	第一个模式匹配完成后退出或立即退出;
r∶	后面接filename,表示从另一个文件中读文本,类似输入重定向 <
s∶	使用指定模式去替换匹配到模式,可以直接进行取代的工作!通常这个 s 的动作可以搭配正规表达式!例如 1,20s/old/new/g;
w∶	后面接filename,表示把行写入一个文件;
x:	表示互换模板块中的文本和缓冲区中的文本;
y:	表示把一个字符翻译为另外的字符(但是不用于正则表达式)
=∶	表示打印行号;
{}∶	当用到sed不同的标记参数(就是前面没有-的参数)时,用大括号{},且不同标记参数之间用分号隔开

   ( 3.1 ) 单行追加

 1 [root@ mysql-master ~]# cat test.txt
 2 I love linux.
 3 
 4 I like badminton ball ,billiard ball and chinese chess!
 5 my blog is http://blog.51cto.com
 6 our site is http://www.aaa.org
 7 my qq num is 49000448.
 8 
 9 ABVGSRGDRH
10 
11 not 4900000448.
12 my god!
13 
14 
15 
16 sed '2a thank you' test.txt      追加thank you 到test.txt第二行后(此法追加只是临时显示)
17 
18 sed -i '2a thank you' test.txt    永久改变文件前边必须加参数-i

  ( 3.2 ) 多行追加

   sed '2a thank you\ngood' test.txt 追加thank you和good到test.txt第二行后(\n表示回车)   

   

 

 ( 4 )  删除

 

 1 sed '2d' test.txt         删除test.txt中的第二行
 2 
 3 sed '2,5d' test.txt     删除test.txt第2行到第5行
 4 
 5 '3,$d'             删除第3行到最后一行
 6 
 7 '1~2d'            删除奇数行    
 8 
 9 '2~2d'            删除偶数行
10 
11 '1,+2d'         删除第1行+后边两行
12 
13 '/god/d'        删除文件中包含god的行
14 
15 '1d;5d;7d'        删除不规则行数

 

  ( 5.1 )按行替换

 

  sed '2c beautiful' test.txt  把test.txt文件中的第2行替换成beautiful

  

 

  ( 5.2 ) 文本替换

 's#A#B#g'=='s/A/B/g'   查找替换 把A替换为B

 sed -i 's/A/B/g' /data/ett.txt     查找A替换成B

 s:单独使用→将每一行中第一处匹配的字符串进行替换 ==>sed命令 
 
 g:每一行进行全部替换 ==>sed命令s的替换标志之一,非sed命令 
 
 对比得出s前加数字针对某行,不加数字针对所有行;后边加g是全部,加数字是某一处

sed -i '2s#1#3#2' emp.txt

第一个数字意思为:文件中的某行
第二个数字意思为:文件源字符
第三个数字意思为:文件修改后的字符
第四个数字意思为:文件中的某列

 

 小试牛刀:使用sed查看IP地址

 ip a show ens33|sed -n  '3s#.*inet##gp'|sed -n 's#/.*##gp'

 

 3 . awk 

( 3.1 )  awk简介

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

awk 是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华,如 语言等。在 linux 系统日常处理工作中,发挥很重要的作用,掌握了 awk将会使你的工作变的高大上。 awk 是三剑客的老大,利剑出鞘,必会不同凡响。

 

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

使用方法   : awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

 ( 3.2 )  awk 内置变量

ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价于命令行 -F选项
NF                 浏览记录的域的个数
NR                 已读的记录数
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符

$0变量是指整条记录。$1表示当前行的第一个域,$2表示当前行的第二个域,......以此类推。

$NF是number finally,表示最后一列的信息,跟变量NF是有区别的,变量NF统计的是每行列的总数

( 3.3 ) awk 原理 

 通过一个简短的命令 我们就可以理解其工作原理

 

[root@Gin scripts]# awk '{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
.....................................................
 
[root@Gin scripts]# echo hhh|awk '{print "hello,world"}'
hello,world
 
[root@Gin scripts]# awk '{print "hiya"}' /etc/passwd
hiya
hiya
hiya
hiya
···················································

  

你将会见到/etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk时,我们指定/etc/passwd 作为输入文件。执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。

所有输出都发送到 stdout,所得到的结果与执行 cat /etc/passwd 完全相同。
现在,解释{ print }代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。
再次说明, awk 对输入文件中的每一行都执行这个脚本。

  

 

  

1 $ awk -F":" '{ print $1 }' /etc/passwd
2 $ awk -F":" '{ print $1 $3 }' /etc/passwd
3 $ awk -F":" '{ print $1 " " $3 }' /etc/passwd
4 $ awk -F":" '{ print "username: " $1 "\t\tuid:" $3" }' /etc/passwd

-F 指定分隔符为冒号

1
2
3
4
5
6
7
8
[root@localhost ~] # awk -F ':' '{print $1,$2}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown

 awk 常用变量

NF:表示最后一个字段

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin

 $(NF-1):表示倒数第二个字段

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print $(NF-1)}' /etc/passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd

 NR:表示当前处理的是第几行

 输出第二行

1
2
[root@localhost ~] # awk -F ":" 'NR==2 {print}' /etc/passwd
bin:x:1:1:bin: /bin : /sbin/nologin

 

输出第三行以后的行

1
2
3
4
5
[root@localhost ~] # awk -F ':' 'NR>3 {print}' /etc/passwd
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

 

 awk 内置函数

toupper()用于将字符转为大写【t^ber】

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print toupper($1)}' /etc/passwd
ROOT
BIN
DAEMON
ADM
LP

 tolower()用于将字符串转为小写

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print toupper($1)}' /etc/passwd >/tmp/aa.txt
[root@localhost ~] # awk '{print tolower($1)}' /tmp/aa.txt
root
bin
daemon
adm

 

 awk 允许指定输出条件,只输出符合条件的行

打印包含root的行

1
2
3
[root@localhost ~] # awk '/root/ {print}' /etc/passwd
root:x:0:0:root: /root : /bin/bash
operator:x:11:0:operator: /root : /sbin/nologin

 输出第一个字段等于指定值的行

1
2
[root@localhost ~] # awk -F ':' '$1=="root" {print}' /etc/passwd
root:x:0:0:root: /root : /bin/bash

 awk if else语句

假如$1==root 打印第一个字段,否则打印第二个字段

1
2
3
4
5
6
[root@localhost ~] # awk -F : '{if ($1=="root") print $1;else print $2}' /etc/passwd
root
x
x
x
x

 

 awk 高级用法BEGIN END

任何在BEGIN之后列出的操作(在{}内)将在Unix awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。

因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果

数字求和

 

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

 

 

 

 

1
2
3
4
5
6
7
8
9
例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段):
 
cat  sx
 
一:50件:200.00
 
二:60件:300.00
 
三:70件:400.00

 

1
2
3
4
5
6
7
8
[root@localhost ~] # awk 'BEGIN {FS=":";print "统计销售金额";total=0} {print $3;total=total+$3;} END {printf "销售金额总计: %.2f\n",total}' sx
统计销售金额
200.00
 
300.00
 
400.00
销售金额总计: 900.00

AWK 数组

awk可以使用关联数组这种数据结构,索引可以是数字或字符串。

AWK关联数 组也不需要提前声明其大小,因为它在运行时可以自动的增大或减小。

定义数组,并且打印数组元素

1
awk  'BEGIN{a[0]="xiaohong";a[1]="xiaolan";print a[0]}'

 打印所有元素的下标(索引)

1
awk  'BEGIN{a[0]="xiaohong";a[1]="xiaolan";for (i in a)print i;}'

 

 

 统计访问网站的ip地址的个数

 

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~] # awk '{count[$1]} END {for (i in count) print i}' /var/log/httpd/access_log  #打印下标
172.18.47.60
172.18.47.61
127.0.0.1
[root@localhost ~] # awk '{count[$1]++} END {for (i in count) print i}' /var/log/httpd/access_log
172.18.47.60
172.18.47.61
127.0.0.1
[root@localhost ~] # awk '{count[$1]++} END {for (i in count) print i,count[i]}' /var/log/httpd/access_log
172.18.47.60 1001
172.18.47.61 1001
127.0.0.1 1001

 

  小试牛刀:使用awk查看IP地址

 ip a show ens33|grep 'inet'|awk -F ' |/' 'NR==1{print $6}'


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM