正规表示法对于系统管理员来说实在是很重要!!!!
因为系统会产生很多的信息,这些信息有的重要有的仅是告知,此时,管理员可以透过正规表示法的功能来将重要信息撷取出来,并产生便于查阅的报表来简化管理流程。此外,很多的套装软件也都支持正规表示法的分析,例如邮件服务器的过滤机制(过滤垃圾信件)就是很重要的一个例子。所以,您最好要了解正规表示法的相关技能,在未来管理主机时,才能够更精简处理您的日常事务!
8学习目标:
l 熟悉正表达式的概念及其字符
l 熟练使用sed结合正则表达式
l 熟练使用grep结合正则表达式
l 熟练使用awk结合正则表达式
11.1正则表达式
12.1.1正则表达式概念
正则表达式 (Regular Expression, RE, 或称为常规表示法)是透过一些特殊字节的排列,用以『搜寻/取代/删除』一列或多列文字字串,正则表达式就是用在字串的处理上面的一项『表示式』。正规表示法并不是一个工具程序,而是一个字串处理的标准依据,如果您想要以正规表示法的方式处理字串,就得要使用支持正则表达式的工具程序才行,这类的工具程序很多,例如 vi, sed, awk,grep等等
简单说,正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
12.1.2正则表达式的组成
正则表达式有三部分组成:
1, 字符类
2, 数量限定符
3, 位置限定符
例如:找出多有符合xxxxx@xxxx.xxx模式的字符串(也就是mail地址),要求x可以是字母、数字、下划线、小数点、短划线,email地址的每一部分可以有一个或多个x字符,例如abc@ed.com、1_2@789-6.54等,当然,符合这个模式的并不一定是合法的mail地址,但至少可以做一次初步的筛选,筛选掉类似于a.b、c@d等不符合的字符串。再比如说,找出所有符合yyy.yyy.yyy.yyy模式的字符串(IP地址),要求y是0~9的数字,IP地址的每一部分可以有1~3个y字符
1、字符类
字符类(Character Class):上例中的x和y,他们在模式中表示一个字符,但是取值范围是一类字符中的任意一个。
常用的字符类有以下:
符号 |
描述 |
[] |
匹配括号中的任意一个字符 |
- |
在[]中使用,表示字符范围 |
^ |
在[]括号年内的家头,表示匹配括号中字符外的任意一个字符 |
. |
表示意一个字符; |
[[:alpha:]] |
表示任意一个字母; |
[[:alnum:]] |
表示任意一个字母或者数字; |
[[:space:]] |
表示空格; |
[[:punct:]] |
表示任意一个除数字字母和空格以外的可打印字符; |
[[:digit:]] |
表示数字 |
[[:upper:]] |
[A-Z] |
[[:lower:]] |
[a-z] |
举例:example.txt的内容如下
abc9
abcd
ab
bd
cd
hello,world
hello,xy
xy
xy,hello
xy567 hello
567
~
1、验证“.”在shell输入cat example.txt |grep 'abc.',结果如下
[root@rhel7 tmp]# cat example.txt |grep 'abc.'
abc9
abcd
可以看到abc9和abcd都被输出
2、验证“[]”在shell输入cat example.txt |grep '^[abc]d',结果如下
[root@rhel7 tmp]# cat example.txt |grep '^[abc]d'
bd
cd
bd,cd,均被输出
3、验证“特殊字符”在shell输入cat example.txt |grep 'abc[[:digit:]]',结果如下
[root@rhel7 tmp]# cat example.txt |grep 'abc[[:digit:]]'
abc9
[root@rhel7 tmp]#
2、数量限定符
数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个x字符,IP地址的每一部分可以有1-3个y字符
常用的数量限定符如下:
符号 |
描述 |
* |
重复零次或更多次: |
+ |
重复一次或更多次 |
? |
重复零次或一次 |
\{n\} |
重复n次 |
\{n,\} |
重复n次或更多次 |
\{n,m\} |
重复n到m次 :[0-9]\{11\}连续的11的数字 |
举例:
源文件内容如下
b124230
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
b103303
a013386
b044525
m8987131
B081016
M45678
B103303
BADc2345
1.more size.txt | grep '[a-b]' 范围;如[A-Z]即A,B,C一直到Z都符合要求
b124230
b034325
a081016
a022021
a061048
b103303
a013386
b044525
2.more size.txt | grep '[bB]'
b124230
b034325
b103303
b044525
B081016
B103303
BADc2345
3.more size.txt | grep -iv 'b1..*3' -v :查找不包含匹配项的行
b034325
a081016
m7187998
m7282064
a022021
a061048
m9324822
a013386
b044525
m8987131
B081016
M45678
BADc2345
3、位置限定符
位置限定符(Anchor):描述各种字符类以及普通字符之间的位置关系,例如邮件地址分三部分,用普通字符@和.隔开,IP地址分四部分,用.隔开,每一部分都可以用
字符类和数量限定符描述。为了表示位置关系,需要位置限定符的概念,将在下面介绍。
符号 |
描述 |
^ |
以什么开头; eg:^content 匹配行首为content的行 |
& |
以什么结尾;eg: ;$ 匹配行末为;的行 |
^& |
匹配空行; |
\ |
表示转义; |
\<,\> |
”表示左右边界; |
4、特殊字符
符号 |
描述 |
\ |
转义字符,普通字符转为特殊字符,特殊字符转为普通字符 |
() |
将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符 |
| |
连接两个表达式,表示或的关系 |
举例:
1,n(o|either)表示匹配no或者neither
2,([0-9]{1,3}\.){3}[0-9]{1,3}表示匹配一个ip地址
12.2文字处理工具
12.2.1grep 工具
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本2,它的使用权限是所有2用户。
grep 是一个很常见也很常用的命令,他最重要的功能就是进行字串数据的比对,然后将符合使用者需求的字串列印出来。需要说明的是『grep 在数据中查寻一个字串时,是以 "整行" 为单位来进行数据的撷取的!』也就是说,假如一个文件内有 10 行,其中有两行具有你所搜寻的字串,则将那两行显示在萤幕上,其他的就丢弃了
1.grep : 最早的文本匹配程序,使用POSIX定义的基本正则表达式(BRE)来匹配文本。
2.egrep : 扩展式grep,其使用扩展式正规表达式(ERE)来匹配文本。
3.fgrep :快速grep,这个版本匹配固定字符串而非正则表达式。并且是唯一可以并行匹配多个字符串的版本。
如下简单的介绍grep命令:
语法格式:
grep [options ...] pattern-spec [files ...]
用途:
匹配一个或多个模式的文本行。
options:列举常用的参数
常用参数及意义:
-i |
忽略大小写; |
-v |
反选; |
-A |
n:抓取含关键字的行和此行后n行; |
-B |
n:抓取含关键字的行和前n行; |
-E |
抓取多个关键字:grep “root|0|ftp” /tmp/passwd;==egrep |
-n |
输出带关键字行和行号; |
-s |
不显示错误信息; |
-x |
全列符合的列; |
-c |
输出匹配的行数; |
-o |
仅显示匹配到的内容 |
-C |
连同匹配行的上下n行一并显示 |
GREP实例
Eg:源文件url.txt内容如下:
www.baidu.com
http://www.baidu.com
https://www.baidu.com
http://wwwbaiducom
baidu.com
baidu
1.url匹配
匹配以http或者https开头,并且其后为:并且含有.的串
BRE匹配:
grep '^https\{0,1\}.*\..*' url.txt
匹配结果如下:
http://www.baidu.com
https://www.baidu.com
2.Email匹配
示例文件内容为:
hfutwyy@qq.com
aaaa@
aaa@.com
aaa@gmail.com
@@baidu.com
匹配以字母数字或者下划线开头的多个字符,其后有一个@之后有多个字母数字或者下划线,其中有一个.号
grep '^[[:alpha:][:digit:]_]*@[[:alpha:][:digit:]]*\..*' email.txt
匹配结果:
hfutwyy@qq.com
aaa@.com
aaa@gmail.com
12.2.2 sed工具
1. Sed简介
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。2接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。以下介绍的是Gnu版本的Sed 3.02。
2. 定址
可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。
3. Sed命令
调用sed命令有两种形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
sed常用参数
符号 |
描述 |
-n |
使用安静(silent)模式。 |
-e |
直接在指令列模式上进行 sed 的动作编辑; |
-f |
直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作; |
-r |
sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法) |
-i |
直接修改读取的档案内容,而不是由萤幕输出。 |
Sed常用命令
符号 |
描述 |
d |
删除行:sed 1,3d /tmp/passwd 删除1到3行; |
s |
替换:sed 1,2s/原/新/g /tmp/passwd;g位表示一行中的所有,n表示第n个 |
y |
字符转换:sed ‘y/adc/123/’/tmp/passwd;将adc逐字替换为123; |
i\ |
在前面插入一行:sed ‘2i 1root’/tmp/passwd;在第二行前插入root; |
a\ |
追加:sed '/^test/a\this is a example' example :this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。 |
r |
读入文本并插入到匹配行后: sed '/ftp/r aa' passwd |
p |
打印:sed 1,2p /tmp/passwd ;打印第一到第二行; |
c\ |
以行为单位的替换与显示:nl /etc/passwd | sed '2,5c No 2-5 number' |
{} |
在定位行执行的命令组 |
n |
读取一下个输入行,用下一个命令处理新的行 |
w |
将文本写入到一个文件 |
h |
将模式缓冲区的文本复制到保持缓冲区 |
x |
互换模式缓冲区和保持缓冲区的内容 |
! |
对所选行以外的行进行处理 |
4. 实例
删除:d命令
*
$ sed '2d' example-----删除example文件的第二行。
*
$ sed '2,$d' example-----删除example文件的第二行到末尾所有行。
*
$ sed '$d' example-----删除example文件的最后一行。
*
$ sed '/test/'d example-----删除example文件所有包含test的行。
替换:s命令
*
$ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。
*
$ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。
*
$ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。
*
$ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。
*
$ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。
选定行的范围:逗号
*
$ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。
*
$ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。
*
$ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。
多点编辑:e命令
*
$ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执 行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
*
$ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。
从文件读入:r命令
$ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。
写入文件:w命令
*
$ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。
追加命令:a命令
*
$ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。
插入:i命令
$ sed '/test/i\\
new line
-------------------------' example
如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。
下一个:n命令
*
$ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。
变形:y命令
*
$ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。
退出:q命令
*
$ sed '10q' example-----打印完第10行后,退出sed。
保持和获取:h命令和G命令
$ sed -e '/test/h' -e '$G example-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保 持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中 的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
12.2.3 awk 工具
简介
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
格式
awk '{pattern + action}' {filenames}
尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。
通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
// 匹配代码块,可以是字符串或正则表达式
{} 命令代码块,包含一条或多条命令
; 多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
入门实例
假设last -n 5的输出如下
[root@www ~]# last -n 5 <==仅取出前五行
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
如果只是显示最近登录的5个帐号和ip
[root@www ~]# last -n 5 | awk '{print $1 "\t" $3}'
root 192.168.1.100
root 192.168.1.100
root 192.168.1.100
dmtsai 192.168.1.100
root Fri
上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开
整个 awk 的处理流程是:
1,读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
2,依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3,做完所有的动作与条件类型;
4,若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』,而『以栏位为最小的处理单位』。
awk 的内建变量
变量名称 |
代表意义 |
NF |
每一行 ($0) 拥有的栏位总数 |
NR |
目前 awk 所处理的是『第几行』数据 |
FS |
目前的分隔字节,默认是空白键 |
我们继续以上面 last -n 5 的例子来做说明,如果我想要:
列出每一行的帐号(就是 $1);
列出目前处理的行数(就是 awk 内的 NR 变量)
并且说明,该行有多少栏位(就是 awk 内的 NF 变量)
root@www ~]# last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}'
root lines: 1 columns: 10
root lines: 2 columns: 10
root lines: 3 columns: 10
dmtsai lines: 4 columns: 10
root lines: 5 columns: 9
# 注意,在 awk 内的 NR, NF 等变量要用大写,且不需要有 $ !
特殊要点:
$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符, 默认也是空格,可以改为制表符等
ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕
-F'[:#/]' 定义三个分隔符
统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:
#awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
省略ing---
打印print
print 是awk打印指定内容的主要命令
awk '{print $0}' /etc/passwd ##表示整行输出
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。
printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
print 是awk打印指定内容的主要命令
awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd
awk '{print " "}' /etc/passwd //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本
awk '{print "a"}' /etc/passwd //输出相同个数的a行,一行只有一个a字母
awk -F":" '{print $1}' /etc/passwd
awk -F: '{print $1; print $2}' /etc/passwd //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本
awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd //输出字段1,3,6,以制表符作为分隔符
-f指定脚本文件
格式:awk -f script.awk file
BEGIN{
FS=":"
}
{print $1} //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定
awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test
I find 4 blank lines.
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' //计算文件大小
total size is 17487
-F指定分隔符
$1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符
一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格
awk -F":" '{print $1}' /etc/passwd
awk -F":" '{print $1 $3}' /etc/passwd //$1与$3相连输出,不分隔
awk -F":" '{print $1,$3}' /etc/passwd //多了一个逗号,$1与$3使用空格分隔
awk -F":" '{print $1 " " $3}' /etc/passwd //$1与$3之间手动添加空格分隔
awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd //自定义输出
awk -F: '{print NF}' /etc/passwd //显示每行有多少字段
awk -F: '{print $NF}' /etc/passwd //将每行第NF个字段的值打印出来
awk -F: 'NF==4 {print }' /etc/passwd //显示只有4个字段的行
awk -F: 'NF>2{print $0}' /etc/passwd //显示每行字段数量大于2的行
awk '{print NR,$0}' /etc/passwd //输出每行的行号
awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //依次打印行号,字段数,最后字段值,制表符,每行内容
awk -F: 'NR==5{print}' /etc/passwd //显示第5行
awk -F: 'NR==5 || NR==6{print}' /etc/passwd //显示第5行和第6行
route -n|awk 'NR!=1{print}' //不显示第一行
//匹配代码块
//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~//字段值不匹配 ~/a1|a2/字段值匹配a1或a2
awk '/mysql/' /etc/passwd
awk '/mysql/{print }' /etc/passwd
awk '/mysql/{print $0}' /etc/passwd //三条指令结果一样
awk '!/mysql/{print $0}' /etc/passwd //输出不匹配mysql的行
awk '/mysql|mail/{print}' /etc/passwd
awk '!/mysql|mail/{print}' /etc/passwd
awk -F: '/mail/,/mysql/{print}' /etc/passwd //区间匹配
awk '/[2][7][7]*/{print $0}' /etc/passwd //匹配包含27为数字开头的行,如27,277,2777...
awk -F: '$1~/mail/{print $1}' /etc/passwd //$1匹配指定内容才显示
awk -F: '{if($1~/mail/) print $1}' /etc/passwd //与上面相同
awk -F: '$1!~/mail/{print $1}' /etc/passwd //不匹配
awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd
IF语句
必须用在{}中,且比较内容用()扩起来
awk -F: '{if($1~/mail/) print $1}' /etc/passwd //简写
awk -F: '{if($1~/mail/) {print $1}}' /etc/passwd //全写
awk -F: '{if($1~/mail/) {print $1} else {print $2}}' /etc/passwd //if...else...
awk -F: '{if($3>100) print "large"; else print "small"}' /etc/passwd
条件表达式
== != > >=
awk -F":" '$1=="mysql"{print $3}' /etc/passwd
awk -F":" '{if($1=="mysql") print $3}' /etc/passwd //与上面相同
awk -F":" '$1!="mysql"{print $3}' /etc/passwd //不等于
awk -F":" '$3>1000{print $3}' /etc/passwd //大于
awk -F":" '$3>=100{print $3}' /etc/passwd //大于等于
awk -F":" '$3<1{print $3}' /etc/passwd //小于
awk -F":" '$3<=1{print $3}' /etc/passwd //小于等于
逻辑运算符
&& 相与的条件同时成立结果才为真
|| 相或的条件一个成立结果及为真
awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd //逻辑与,$1匹配mail,并且$3>8
awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd
awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd //逻辑或
awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd
数值运算
awk -F: '$3 > 100' /etc/passwd
awk -F: '$3 > 100 || $3 < 5' /etc/passwd
awk -F: '$3+$4 > 200' /etc/passwd
awk -F: '/mysql|mail/{print $3+10}' /etc/passwd //第三个字段加10打印
awk -F: '/mysql/{print $3-$4}' /etc/passwd //减法
awk -F: '/mysql/{print $3*$4}' /etc/passwd //求乘积
awk '/MemFree/{print $2/1024}' /proc/meminfo //除法
awk '/MemFree/{print int($2/1024)}' /proc/meminfo //取整
输出分隔符OFS
awk -F: '$6~/\/sbin/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" /etc/passwd
打印/etc/passwd中第六哥字段为/sbin和第一行的4,5,6字段并且以制表符为间隔
输出处理结果到文件
①在命令代码块中直接输出 route -n|awk 'NR!=1{print > "./fs"}'
②使用重定向进行输出 route -n|awk 'NR!=1{print}' > ./fs
while语句
与if语句作用相同
awk -F: 'BEGIN{i=1} {while(i<NF) print NF,$i,i++}' /etc/passwd
打印出总共的字段数和每个字段的内容及字段号
BEGIN,END
BEGIN在命令前执行的操作
END在命令执行后的操作
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' //计算文件大小
total size is 17487
BEGIN初始化变量sum
END打印出变量的值
第十二章节总结:
作为系统管理员每都要处理大量的文字信息,正则表达式和文字处理工具的结合能帮助我们更快的找到自己需要的信息,如查看日志,所以熟练使用正则和文字工具对于系统管理员式十分重要的,我们需要通过练习使用来快速熟悉,最后做下重点回顾:
· 正规表示法就是处理字串的方法,他是以行为单位来进行字串的处理行为;
· 正规表示法透过一些特殊符号的辅助,可以让使用者轻易的达到『搜寻/删除/取代』某特定字串的处理程序;
· 只要工具程序支持正规表示法,那么该工具程序就可以用来作为正规表示法的字串处理之用;
· 正则表达式与万用字节是完全不一样的东西!万用字节 (wildcard) 代表的是 bash 操作介面的一个功能, 但 正则表达式是一种字串处理的表示方式!
· grep 与 egrep 在正规表示法里面是很常见的两支程序,其中, egrep 支持更严谨的正规表示法的语法;
· 由於严谨度的不同,正规表示法之上还有更严谨的延伸正规表示法;
· 基础正规表示法的特殊字符有: *, ?, [], [-], [^], ^, $ 等!
· 常见的正规表示法工具有: grep , sed, vim 等等
· printf 可以透过一些特殊符号来将数据进行格式化输出;
awk 可以使用『栏位』为依据,进行数据的重新整理与输出