网络安全快速入门(六)Linux三剑客及正则表达式

6.1 简介

        我们之前已经了解了一些Linux的基础知识和命令,我们今天来了解Linux三剑客及正则表达式。三剑客,其实就是三个命令,分别是grep、sed及awk;这三个命令主要是用于处理文本文件的三个命令,下面我们就来学习一下这三个命令。

6.2 grep

简介:

        grep和vi一样,也是一模式化的工具

        在grep的时候,是针对每一行进行一次过滤,判断这行是否有满足条件的内容,如果有就显示这行;否则不显示。

格式:

grep [选项] "匹配的内容" 目标文件
cat 目标文件 | grep [选项] "匹配的内容"

选项:

  • -v:取反
  • -o:显示匹配的内容

        (另外因为还有拓展正则表达式的原因,一般在grep后面要加-E来确保拓展正则表达式可以运行,因此建议后面直接跟-E)

话不多说直接举例

a
aa
aaa
aaab
aaaaaavbbbb
adsa
bbbaaabababa
abafafadasdddwadwad
#
@
@#
#@

上述是我创建的b.txt文件,现在要用grep筛选出有a的字段

grep a b.txt

看结果

a
aa
aaa
aaab
aaaaaavbbbb
adsa
bbbaaabababa
abafafadasdddwadwad

带a的字段全部筛选出来了,现在筛选ab字段

grep ab b.txt

看结果

aaab
bbbaaabababa
abafafadasdddwadwad

筛选出来了,现在只筛选出不包含ab字段的行

grep -v ab b.txt

看结果

a
aa
aaa
aaaaaavbbbb
adsa
#
@
@#
#@

可以看到还是有一些aaabbb,因为程序将ab认定成为一个字段,从而只取反ab字段,而不是a和b两个字段。,所以输出结果如上。下一个

6.3 sed

简介

在处理文本文件时会将文本加载到内存中,,然后对内存中的文件副本进行处理。文件中的原始内容不受影响。

格式:

sed [选项] 操作 目标文件
sed “s/要替换的内容/替换的内容/g” 目标文件

选项:

  • -i:修改原始文件【如果不加-i,那就是仅仅修改内存中的文件副本】

举例:

还是用刚刚的文档举例,将文档中第一行的a修改为b,命令如下

sed "s/a/b/g" b.txt

看结果

b
bb
bbb
bbbb
bbbbbbvbbbb
bdsb
bbbbbbbbbbbb
bbbfbfbdbsdddwbdwbd
#
@
@#
#@

        可以看到不仅仅只改了一行,而是全都进行了修改,那是因为内容不够具有唯一性,因此系统执行了批量修改,所以:

要确定修改内容具有唯一性,才能够进行单一字符修改,否则会进行批量修改!!

        但是:因为刚刚我没有加选项-i,因此文档内容依然保持不变,只是在内存进行修改,文档名保持不变,因此我们找一个单一点的进行修改。

例子2:

将b.txt的aaaaaavbbbb修改为ch225

sed "s/aaaaaavbbbb/ch225/g" b.txt

看结果

a
aa
aaa
aaab
ch225
adsa
bbbaaabababa
abafafadasdddwadwad
#
@
@#
#@

完成,接下来来看下一个案例

例子3:

我们创建一个c.txt,文本里面就只写一句话“/room/”。把“/”改为"\ ",该怎么操作

上命令

sed "s# / # \ #g" c.txt

看结果

/roomr/

这里我们发现了,当我们要修改“/”时,我们可以用其他符号进行分隔,一般我们用“#”进行分隔。

例子4:

我们想删除b.txt文件中的第一行内容,我们可以通过下述命令进行操作


 

sed -i 4d b.txt

看结果

a
aa
aaa
adsa
bbbaaabababa
abafafadasdddwadwad
#
@
@#
#@

原本的“aaab”不见了,这就是sed中删除文件某一行的内容。

6.4awk

简介:

截取文件中每行的指定字段

格式:

awk -F "分隔符" '{print $数字}' 文件名

这里要说一个概念,记录,分隔符及字段,我们先来一个完整的命令

awk -F "/" '{print $3}'
        |           |
      分隔符      字段   

举个例子:

root   :      x     :       0       :      0      :      root     :   /root    :  /bin/bash
  |    |      |     |       |       |      |      |       |       |      |     |      |
字段1 分隔符 字段2 分隔符  字段3  分隔符 字段4   分隔符 字段5  分隔符  字段6 分隔符字段7

        在这行中如果我们用:作为分隔符,那么分隔后字段如上:

因此我们引入一个概念

概念:

  • 记录:文件中的每一行都是一条记录
  • 分隔符:分割每一行的符号
  • 字段:一条记录被分隔符分割后的每一块都是一个字段

        我们已经知道这一点了,接下来我们来看看实例

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

例子1:

        上面为我们要操作的文档c.txt,我们现在提取每行“:”后面的第三个字段,

 awk -F":" '{print $3}' c.txt 

        看输出结果

0
1
2
3
4

完成,下一个例子。

例子2:

        截取/下的最后一个字段

awk -F "/" '{print $NF}' c.txt 

        看结果:

bash
nologin
nologin
nologin
nologin

例子3:

        查看各行"/"分隔符分隔的字段数

awk -F "/" '{print NF}' c.txt

看结果

1
4
4
4
5
6

例子4:

        用输出c.txt的所有字符

[root@localhost /]# awk -F"n" '{print $0}' c.txt 

看结果

[root@localhost /]# awk -F"n" '{print $0}' c.txt 
[root@localhost ~]# cat a.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

        可以看出,这里有三个特殊字符,我们来归纳一下

特殊数字(在字段数输入)

  • 0:输出整条记录
  • NF: 查看各行"/"分隔符分隔的字段数
  • $NF:输出各行的最后一个字段

        我们来接着看例子

例子5:

        查看用":"和"/"中共同分隔的第七个字段

awk -F "[/:]+" '{print $7}' c.txt

看结果

root
bin
sbin
var
var

注意:连续使用多个分隔符[/:]等特殊符号,,需要加“[]”,加“+”意味着将之前多个分隔符视为一个分割点;还要注意的是,分隔符什么都可以加,但空格必须放在最后!!!

例子6:

        在第三行筛选出以“/” 分隔符分隔出来的第个二个字符段

 awk -F "/" 'NR==3{print $2}' c.txt

看结果

bin:

       这里还有一个字符:NR==3。这里是指定第三行字符,那这个命令就是在第三行筛选出以“/”分隔符分割出的第五个字符段。

6.5 正则表达式

        上面我们看了三剑客,上面三个命令主要是为了提取一些文本文件中的特殊字符及字段,为了扩展它们的用法,这里在三剑客后面正则表达式可以实现拓展它们的用法,因此衍生除了正则表达式。正则表达,就是一些具有特殊含义的符号,比如?  .    *   +  ^   $   ()   {}等。

        从符号上来看,这跟我们之前学的通配符有些相似,但又不完全相同。我们可以这样记

  • 通配符:针对文件名进行匹配查找的
  • 正则表达式:针对文件的内容进行匹配查找的

接下来我们就来看看这个内容

(1)基本正则

6.5.1 匹配位置

一般搭配三剑客进行使用,

        匹配行首

^

        匹配行尾

$

        匹配单词首部

\<

        匹配单词尾部

\>

        匹配位置就这些,接下来我们据一些例子看看这些怎么用

这是我们的目标文件c.txt,我们用他进行实验

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

例子1:

        找到包含root的行

grep "root" c.txt

看结果

[root@localhost ~]# cat a.txt 
root:x:0:0:root:/root:/bin/bash

例子2:

        找到以root为开头的行

grep "^root" c.txt 

看结果

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

例子3:

        找到以bash为结尾的行

grep "bash$" c.txt

看结果

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

例子4:

        找到以包含#的行

grep "#" c.txt 

看结果

[root@localhost ~]# cat a.txt 

例子五:

        找到包含root单词的行

grep "\<root\>" c.txt 

看结果

[root@localhost ~]# cat a.txt 
root:x:0:0:root:/root:/bin/bash

好了,我们现在来总结一下上述例子,在上述例子中我们分别用到了包含、匹配行首,匹配行尾,匹配单词首部,匹配单词尾部、锚定首部尾部等一些匹配位置格式,接下来我们来看看匹配范围。

6.5.2 匹配范围

        匹配范围,顾名思义,就是限定一个房子那位,用来查看文件中的一些特殊字符是否出现,一般先顶一个范围用[]来限定,有点类似于通配符中的’?‘,只不过,一个应用于目录,一个应用于文本文件中,匹配范围搭配三剑客效果更佳奥o·

匹配范围基础格式

常用匹配范围格式

        匹配范围有两种写法,我们先来列举写法一

写法一
[] 表示限定一个范围
 
[0-9] 表示0-9之间的任意一个数字
[a-z] 表示任意一个小写字母
[A-Z] 表示任意一个大写字母
[0-9a-zA-Z] 表示任意一个数字或者字母
[a-zA-Z] 表示任意一个字母 = [a-Z]
[^]匹配范围以外的字符
写法二
[[:space:]] 表示一个空格
[[:digit:]] 表示任意一个数字
[[:lower:]] 表示任意一个小写字母
[[:upper:]] 表示任意一个大写字母
[[:alnum:]] 表示任意一个数字或者字母
[[:punct:]] 表示任意一个符号
 
[[:digit:][:space:]] 表示一个空格或者任意一个数字

注意:[  ]为固定的,只能表示限定一个范围,不管方法一还是方法二都要用到它,这里我们来通过一些例子来理解匹配范围格式;

        目标文件b.txt如下

a
aa
aaa
adsa
bbbaaabababa
abafafadasdddwadwad
#
@
@#
#@
 @# 
@# 
]   @
  @# @ @#$
aaaabbbbbbb
AA
bbb
aaaaAAAbbb
aaasssssaaad

        我们来开始举例

例子1:

        匹配以字母a或者b开头的数字

grep "[ab]" b.txt

看结果

(这里要注意的是,因为程序执行结果是笔者复制粘贴过来的,因此会没有高亮效果,只能用图片表示输出结果,希望各位理解)

        可以看到,a和b会高亮显示出来,因为“【】”只能限定一个范围,因此程序执行时高亮a或b,所以只要行里面有a或b的就会全部列出来!

例子2:

        匹配以“空格或者#或者@开头的”行

grep "^[ #@]" b.txt 

看结果

第二种写法:

grep "^[[:space:] @ #]" b.txt 

例子3:

        匹配以空格开头,后面是@,@后是非空字符的行

grep "^[[:space:]][@][[:punct:]]" b.txt 

看结果

第二种写法

 grep "^[ ][@][[:punct:]]" b.txt 

        我们一点点来读,首先定义行首为空格,其次后面跟一个@符,最后一个非空字符,非空字符。因为方法一的空格用特定的一个命令,因此方括号就显得多了点,但其实本质不变,最终输出结果都是一样的。下一个:

例子4:

        匹配a b c以外的字符

 grep "[^abc]" b.txt 

看结果

        (注意:^在方括号外面为匹配行首,^在方括号以内为范围以外的行首)

那么问题来了,我们之间grep -v能不能实现取反效果呢?

试试看

 grep -v "abc" b.txt 

看结果

        可以看到,上面有高亮,下面我们取反没有高亮。

下一个例子

匹配不是以a b c为开头的行

[root@localhost /]# grep "^[^abc]" b.txt 

看结果

常用的匹配范围基本上就这么多了,但由于现实中由于实现目的不同,因此需要用到的命令格式也不尽相同,这里只是举出一些常用例子供大家参考。

6.5.3 次数匹配

        我们已经用到了匹配位置和匹配范围,但是在日常生活中,这些似乎不太够用,有些字段重复出现,我们需要筛选出一些重复字段,这个时候我们就要用到次数匹配了。

常用次数匹配的字符
. 表示任意一个字符
* 表示其前面的字符出现任意次数【任意次可以是 0次 1次 无数次】
\{m,n\} 其前面的字符出现最少m次,最多n次
 \{3,7\} 表示其前面的字符出现最少3次,最多7次
 \{3,\} 表示其前面的字符出现最少3次
 \{,7\} 表示其前面的字符出现最多7次
 \{3,3\} 表示其前面的字符出现3次
? 表其前面的字符出现0次或者1次[最多一次] - 扩展正则的选项
+ 表其前面的字符出现最少一次 - 扩展正则的选项

(注意:?和+为拓展正则表达式,如需引用需要在命令前加上-E,或者使用egrep来直接使用拓展正则表达式)

        通过次数匹配和前面的一些其他匹配条件结合就会容易很多,我们直接来举例,还是用的文件b.txt

文本文件如下:

a
aa
aaa
adsa
bbbaaabababa
abafafadasdddwadwad
#
@
@#
#@
 @# 
@# 
]   @
  @# @ @#$
aaaabbbbbbb
AA
bbb
aaaaAAAbbb
aaasssssaaad

        上例子!!!

例子1:

        匹配文件中a前面至少三个b的行

[root@localhost /]# grep ^"b\{3,\}a" b.txt 

看结果


案例2:

        匹配文件中a前面最多有一个b的行

 grep "b\{,1\}a" b.txt 

看结果

写法2:

egrep "b?a" b.txt 

        这里我们看到了,a前面没有b也进行输出了,这是因为前面设置的是?,最多不超过一,但也包含0,因此输出如下结果,如果想要绝对的话看下面写法

写法3:

grep "b\{1,1\}a" b.txt 

看结果

这样就可以绝对去筛选了

案例3:

        过滤文件中a前面至少有一个b的行

 egrep "b+a" b.txt 

看结果

        接下来我们说一个常见的组合

.* 可表示任意个任意字符

        这个组合跟通配符里面的*一样,都是表示任意个任意字符,那么问题来了,下面这个代码会输出什么?或者说什么会高亮?

 grep "a*b" b.txt

        我们直接来看结果

        那么问题来了,为什么他b前面没a也输出啊?

        揭晓答案,因为*表示前面出现的字符的任意次数,这个任意可以为无限个,当然也可以为0个,因此会出现上述结果。

        了解了这个,我们接着来看例子

例子4:

匹配以a为开头的行,而且以d为结尾的行

grep "^a.*d$" b.txt

看结果

因为篇幅问题,笔者只是抓住了一些重点进行操作,其他像    .   没有细说,这个是表示任意一个字符,类似通配符中的?,麻烦各位读者自行尝试0..0.

6.5.4 分组

        上述三个匹配格式已经可以拿捏大部分数据了,但有时候我们可能需要定位一个分组并进行多次筛选,用上面的格式显得有些过于复杂,因此我们用分组来解决问题;分组,类似于之前python所讲的占位符,通过一个特殊标定点的来引用前面匹配的内容进行第二次筛选,我们先来看一下分组格式:

分组格式:
\( 定位分组的位置 \)
\1 引用第一个分组的内容
\2 引用第二个分组的内容

        来举个例子看看它的用法吧,测试代码

163365e463gukj6
347h42dju5rnj4G
756trtr5yuh454
fhgeeg434ghhgt44hegh
ch22567890
lscdmvmkdirrmvilspjab
@$Frffdldm*#%^&
a  f   h
g
g
ddd
g yhh

        匹配出现两个相同数字的行

 grep "\([0-9]\).*\1" a.txt 

        我们来看结果

        可以看到,第一行6-6,第二行4-4,第三行5-5,第四行4-4,第五行22,都是两个相同的数字,那么问题来了,我要两个连续相同的数字怎么办?

命令如下:

grep "\([0-9]\)\1" a.txt 

看结果

        两个连续相同的数字,可以看到,跟上面命令的区别是没有加".  *  "   。因此程序判定两个分组需要去连接执行。如果我们要找两组两个连续相同的数字呢?

命令如下:

grep "\([0-9][0-9]\).*\1" a.txt

看结果

        可以看到,在标识符前面用”   .*    “ 连接可以实现中间有任意数量的任意字符串的筛选,现在我们实现的是63开头63结束,中间为任意字符串的效果。

6.5.5  或

        或,顾名思义就是输出两个分组中的任意一个分组,我们来看一下。

或的字符:

 | 或

这个东西比较简单,用文字表述可能不够清楚,因此这里直接上例子,测试文件如下

sadfa cat asfasdf Cat a asdf 

我们现在要筛选出Cat和cat,现在直接来看用法

egrep "(c|C)at" b.txt

注意:因为”或“属于扩展正则表达式,所以需要在前面加上e或者在后面加上选项-E来实现命令的正常运行!!!

看输出

写法二:

egrep "(cat|Cat)" b.txt

那么问题来了,我写下面的代码可以吗

 egrep "(c|Cat)" b.txt 

话不多说直接看输出

看样子不行,那是因为 将c为一个匹配对象,Cat为一个匹配对象,所以系统默认匹配的是c或Cat而不是cat和Cat,这里需要注意!!!

最后给大家放一个案例,如果能看懂下列命令的话说明笔者的内容还是有一点点质量的。

测试文件d.txt如下

dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
cwdhrony:x:998:996::/var/lib/chrony:/sbin/nologin

看命令猜字段

  

cat d.txt | awk -F":" 'NR==3{print $3}'

大家想一想这个输出什么字符:

        好了,以上就是关于三剑客和正则表达式的内容,内容有些遗漏或错误还请各位评论区指正,感谢各位的观看!

  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值