加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

grep与正则表达式

发布时间:2020-12-14 00:46:13 所属栏目:百科 来源:网络整理
导读:回顾: bash 的特性: hash ,变量 命令: hash : hash 命令 变量: 本地变量,环境变量,局部变量 位置参数变量,特殊变量 变量赋值: name=value , exportname=value , declare -x name=value 变量引用: $name , ${name} 有些时候,变量的引用时用 ${

回顾:

bash的特性:hash,变量

命令:hashhash命令

变量:

本地变量,环境变量,局部变量

位置参数变量,特殊变量

变量赋值:name=valueexportname=valuedeclare -x name=value

变量引用:$name${name}

有些时候,变量的引用时用${name},即大括号是不能省略的,

演示:

[root@centos6 ~]#animal=sheep

[root@centos6~]# echo $animal

sheep

[root@centos6~]# echo "these is$animals"

theseis

[root@centos6~]# echo "these is${animal}s" //我们希望将 sheep编程复数,所以这时候就需要加上大括号。

theseis sheeps

[root@centos6~]#

撤销:unset name

(变量的声明,他的作用域仅仅是作用在当前的shell进程,对于环境变量而言,他的作用于也仅仅是作用在当前的shell及其子进程上,如果我们现在的进程终止了,我们还需要启动一个进程,依然想让它有效,则需要编辑配置文件来实现,需要定义在配置文件中,)

bash脚本编程,运行脚本

运行脚本:

1)给脚本执行权限,然后运行

2)直接手动使用bash解释器,将脚本作为bash的参数来运行

编写脚本编程标准:

1)第一行必须要顶格写,#!/bin/bash

2)在脚本中的所有的“#”都被注释掉。所有的空白行也会被注释掉

3)建议在脚本编写过程中,分段时我们空几行,可以提高阅读

bash的配置文件

profile类:登录式shell提供

登录式shell

使用 su - 或使用 su -l 或者通过终端直接登录的用户,

bashrc类:非登录式shell提供

使用su切换时,中间没有加“-”或“-l”选项,在图形环境下,使用命令行接口,shell脚本运行时运行的shell进程,

登录式shell运行时,读取的配置文件的路径顺序:

/etc/profile------>/etc/profile.d/*.sh------->~/.bash_profile--------->~/.bashrc--------->/etc/bashrc

非登录式shell运行时,读取的配置文件的路径顺序:

~/.bashrc-------->/etc/bashrc-------->/etc/profile.d/*.sh

profile类的配置文件主要用于实现定义环境变量,或定义运行的命令或脚本

bashrc类的配置文件主要用于定义本地变量和命令别名。

文本处理工具:

Linux上的文本处理三剑客:

grep:文本过滤工具(以模式进行过滤:pattern)工具:

sedstream editor,流编辑器;所以说sed是文本编辑器;

awkLinux上的实现为gawk,文本报告生成器(即:格式华文本);

正则表达式:Regual Expressiion 简写为:REGEXP

文本处理三剑客,都会用到正则表达式。

定义:

由一类特殊字符文本字符所编写的模式,其中有些字符不表示其字面意义, 而是用于表示控制或通配的功能;像这样的组合我们就称之为“正则表达式”

正则表达式分为两类:

基本正则表达式:BRE

扩展正则表达式:ERE

两者不同的地方就是他们的元字符不同

元字符:表示这种字符不会再被切割,而且是用于通配或者是控制的功能。

基本正则表达式的元字符与扩展正则表达式的元字符还是不一样的。

举例:

我们要匹配找到一个单词连续出现三次,写一个模式: hello”单词至少出现三次,并且后面还带有空格的,这个空格至少出现一次,然后由“hello和空格组成的模式,还可以在文本中出现n次,那么闷应该怎样写:

解: (hello[[:space:]]+)+

正则表达式的出现,是计算机得以智能化的非常重要的科学工具。

计算机存储的数据,一般为两类:文本类,数值类

grep工具:

grep:全称:Global searchREgular expression and Print out the line.

作用:全面的搜索文本文件的工具,根据用户指定的“模式”(过滤条件)对目标文本逐行进程匹配检查;打印出匹配到的一整行而不是仅仅打印匹配到的模式本身

模式:由正则表达式的元字符文本字符所编写出的过滤条件

每一个正则表达式的模式的实现,都要用到正则表达式的引擎,也称为正则表达式处理器,就像grep工具,之所以能够根据模式来过滤文本,就是grep工具本身自带了“正则表达式的引擎工具”不同的正则表达式的引擎所能支持的元字符,支持的正则表达式的种类,无论是基本的还是扩展的都是不一样的。

就连grepsedawk这三个工具他们内置的正则表达式引擎也是不一样的。

正则表达式引擎:

grep[OPTIONS] PATTERN [FILE]..... //解释:grep命令字,后加选项,PATTERN是我们 自己编写的查找条件,也就是模式;FILE是指我们 要对哪个文件进行过滤

grep[OPTIONS] [-e PATTERN] -f FILE (FILE............) //加上选项“-e”表示可以写多个查找 条件,加上选项“-f”表示我们可以将模 式写在一个文件中,然后读取这个文件来 对后面的括号中的目标文件进行过滤查

OPTIONS(选项):

--color=auto对匹配到的文本着色后高亮显示(默认是红色,但是我们也可以将这 个颜色改为其他的颜色.)

-iignorecase,忽略字符大小写;

-o:仅显示匹配到的字符串本身;

-V,--invert-match:显示不能被模式匹配到的行;

-E:支持使用扩展的正则表达式元字符;

-q,--quiet,--silent:静默模式,既不输出任何信息;

-A#after,#行(#:表示一个数字)

-B#before,前#

-C#context,前后各#

-E:支持使用扩产一表达式

基本正则表达式元字符:

字符匹配

.:一个点号,匹配任意单个字符;

[]:匹配指定范围内的任意单个字符;

[^]:匹配指定范围之外的任意单个字符;

[:digit:] [:lower:] [:upper:] [:alpha:] [:alnum:] [:punct:] [:space:]

注意:我们在使用上面的待码时,我们还需要在外面加上范围符号“[]”。

练习:

1)在文件/etc/passwd中匹配rt之间有两个任意字母的行:

[root@centos6~]# grep"r[[:alpha:]][[:alpha:]]t" /etc/passwd

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

operator:x:11:0:operator:/root:/sbin/nologin

[root@centos6~]#

2)在文件/etc/fstab中匹配出现“UUID”的行:

[root@centos6~]# grep "UUID"/etc/fstab //模式可以不加双引号,因为是字符串

UUID=2ead7599-15b0-4b11-b96d-5f9b59e2e7eb/ ext4 defaults 1 1

UUID=edb28e3e-5ee7-400f-8226-fab5fa157188/boot ext4 defaults 1 2

UUID=32376552-a128-416d-be08-0aa6acab4661/testdir ext4 defaults 1 2

UUID=091e5b14-8201-4ffc-9278-41b7acae00d9swap swap defaults 0 0

[root@centos6~]#

上面我们匹配“UUID”时,UUID显示为红色,是高亮显示,是因为我们定义了grep的高亮显示别名:“alias grep='grep --color=auto'”这是centOS6centOS7的不同,6系统没有自定义这个别名,而7上定义了,我们可以在centOS6上自行定义

3[root@centos6~]# grep -o UUID /etc/fstab //仅显示匹配到的字符串本身内容

UUID

UUID

UUID

UUID

[root@centos6~]#

4[root@centos6~]# grep -q UUID /etc/fstab //作用就是我们可以根据匹配到或者 匹配不到的结果,来知道没有这个信息

[root@centos6~]# echo $?

0

[root@centos6~]# grep -q UUIID /etc/fstab

[root@centos6~]# echo $?

1

[root@centos6~]#

上面选项“-q”的作用:我们以后可以根据grep是否执行正常的结果。可以当做一种判断条件,我们并不关心grep执行的结果,我们只关心grep执行的状态结果时,我们就可以用“-q”选项了

匹配次数:

用在要指定其出现的次数的字符的后面,用于限制其前面字符出现的次数;默认工作在贪婪模式下

*:匹配其前面的字符任意次0,1次或任意次;

练习:

grep"x*y"

符合条件的有:abxyabyxxxxxyyab

.*:匹配任意长度的任意字符(相当于glob*,匹配任意长度的任意字符,并且正则表达式默认工作在贪婪模式,能匹配多长就匹配多长。)

练习:

grep"r.*" /etc/passwd

wKioL1gytIiiVc_9AAIohkxYN5c745.png

注意:正则表达式的模式时,一般要加上双引号。

?:匹配其前面的字符0次或1次;即前面的字符是可有可无的;

+:匹配前面的字符1次或多次,即其前面的字符要出现至少一次;

{m}:匹配其前面的字符m次;(精确次数匹配)

{m,n}:匹配其前面的字符至少m次,至多n次;

{0,n}:匹配其前面的字符最多n次;

{m,}:匹配其前面的字符最少m次;

位置锚定:

^:行首锚定;用于模式的最左侧;

$:行尾锚定,用于模式的最右侧;

^PATTERN$:用于PATTERN来匹配整行;

^$:空白行;(连空格也不能包含的空行)

^[[:space:]]*$:空行或包含空白字符的行;

单词:非特殊字符所组成的连续字符(字符串)都成为单词;

&;b:词首锚定,用于单词模式的左侧;

&;b:词尾锚定,用于单词模式的右侧;

&;PATTERN&;:匹配完成单词;

练习:

1)显示/etc/passwd文件中不以/bin/bash结尾的行;

[root@centos6~]# grep -v"/bin/bash$" /etc/passwd

2)找出/etc/passwd文件中两位数或三位数;

错误的写法:[root@centos6 ~]# grep"[[:digit:]]{2,3}" /etc/passwd

正确的写法:[root@centos6 ~]# grep"&;[[:digit:]]{2,3}&;" /etc/passwd

或:[root@centos6 ~]# grep"&;[0-9]{2,3}&;" /etc/passwd

总结:这里当匹配确定的几位数时,我们一定要锚定开头和结尾,因为,不锚定的话, 五位数,六位数,等等它都包含三位数。

3)找出/etc/rc.d/rc.sysinit/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行;

错误的写法:grep -v '[[:space:]]$'/etc/rc.d/rc.sysinit | grep '^[[:space:]]+'

正确的写法:[root@centos6 ~]# grep"^[[:space:]]+[^[:space:]]" /etc/rc.d/rc.sysinit

4)找出“netstat-tan”命令的结果中以“LISTEN”后跟0,1,或多个空白字符结尾的行;

分组及引用:

错误的写法:[root@centos6~]# netstat -tan | grep "LISTEN[[:space:]].*$"

正确的写法:[root@centos6~]# netstat -tan | grep"LISTEN[[:space:]]*$"

xy*ab这表示什么意思?

表示前面的y能够出现0次,1次,多多次,跟x是没有关系的;

问题:如果想让上面的xy组成一个整体,然后让这个整体出现1次,0次,或多次;

解:

那就需要将xy括起来,将其看做一个整体单位来描述,但是在bash命令行中括号是有特殊意义的,所以这里我们需要用转义字符;即要写为:(xy)*ab,类似于这样的就叫做分组;

分组及引用:

():将一个或多个字符捆绑在一起,当作一个整体进行处理;

例如:(xy)*ab

Note(注意):分组括号中的模式匹配到的内容会被正则表达式引擎自动记录于内部的 变量中,这些变量为:

1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹 配到的字符;

2

3

........

解释:如果我们有多个括号的话,那么第一个括号所匹配到的内容可以被后面再次引用

举例说明:

例一:

一个文件中有以下内容:

Heloves his lover.

Helikes his lover.

Shelikes her liker.

Sheloves her liker.

现在要求我们找出这个文件中前后出现两个一样的字符串的行,比如说“He loves hislover.”行中有两个love字符串。

第一步:

我们先建立一个名为“lovers.txt”文件,将上面内容复制过去。

我们用nano命令时,我们写完后,先按回车键,然后再按ctrl+x退出。

[root@centos6~]# nano lovers.txt

第二步:

进行查找:

但是我们如果用这个命令查找的话会出现下面的现象:

[root@centos6~]# grep "l..e.*l..e"lovers.txt

wKiom1gytKrBRpJ4AAAWQ2Be598328.png

上面的查找结果显然不符合要求,因为我们要查找的是,前面是like,后面也是like 或者前面是love后面也必须是love,那么这时我们应该怎么办?

[root@centos6~]# grep"(l..e).*1" lovers.txt//这就是后向引用。

wKiom1gytMWzhF0PAAA5ojIDJGg877.png

例二:

我们要找出文件“/etc/passwd”中行首出现root,行中也出现root的行:

解:

[root@centos6~]# grep"(r..t).*1" /etc/passwd

wKiom1gytOLC9ZKgAAAOqrXTydQ183.png

后向引用:引用前面的分组括号中的模式所匹配到的字符;括起来后也可以不引用。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读