一.划水阶段
首先我们先来一个三剑客与正则表达式混合使用的简单示例,大致了解是个啥玩意儿。下面我来演示一下如何查询登录失败的ip地址及次数。
1.首先,进入到 /var/log
目录下
cd /var/log
效果如下
2.最后,输入如下指令即可查看:
grep 'Failed password' secure | grep -Po "(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)" |sort -n |uniq -c
效果如下:
二. 修炼阶段
下面我将把三剑客参数表格集锦都无私奉献与你,请大侠们多多练习,都是基础。冰冻三尺,非一日之寒。
1.grep参数表格
参数 | 解释 |
---|---|
-n | 显示行数 |
-c | 统计行数 |
-i | 不区分大小写 |
-w | 精准匹配 |
-o | 只显示匹配的结果 |
-A1 | after 同时打印搜索结果行的后1行 |
-B2 | before 同时打印搜索结果的前2行 |
-C3 | center 同时打印搜索结果的上下各3行 |
-E | 正则表达式 |
-P | 使用perl正则 |
ps:表格只适用于将下面实例都实操理解后使用。
实例1:过滤出test.txt文件含有tcp的行并且显示行数
grep -n 'tcp' test.txt
效果如下:
实例2:在test.txt文件中精准匹配出tcp
grep -w 'tcp' test.txt
效果如下:
实例3:只过滤tcp三个字母并且统计行数
grep -oc 'tcp' test.txt
效果如下:
实例4:过滤出含有ftp,ssh,telnet的行
grep -E 'ftp|ssh' test.txt
效果如下:
实例5:过滤所有数字
grep -P '\d+' test.txt
效果如下:
实例6:过滤5位数字
grep -P '\d{5,}' test.txt
效果如下
2.sed参数表格
参数 | 参数解释 | 动作 | 动作解释 |
---|---|---|---|
-n | 只将目标行列出 | a | 在指定行后面插入一行 |
-r | 延伸型正则 | d | 删除 |
-r | 修改源文件 | i | 在指定行前面插入一行 |
p | 打印 | ||
s | 替换 |
ps:表格只适用于将下面实例都实操理解后使用。
例1:在test.txt文件里复制行数据里有字母a的
sed '/a/p' test.txt
效果如下:
例2:只打印出含有a字母的行
sed -n '/a/p' test.txt
效果如下:
例3:在test1.txt文件中过滤掉带有tcp的行
sed '/tcp/d' test1.txt
效果如下,
过滤其实有删除的意思在,只不过它只留存在表面上,也就是将删除这几行的结果打印到终端上给你看,但不在原文件里面删除。若要删除原文件里面的内容,只需要在原来的命令上加一个 -i
参数即可。
sed -i '/tcp/d' test1.txt
例4:过滤掉以#号开头的行
sed '/^#/d' test1.txt
效果如下:
同理若要删除原文件里面的内容,只需要在原来的命令上加一个 -i
参数即可。
sed -i '/^#/d' test1.txt
例5:过滤掉1到10行的数据
sed '1,10d' test1.txt
同样,如果你只想过滤第5行:
sed '5d' test1.txt
例6:在第3行后面插入hello
sed '3a hello' test.txt
效果如下:
值得注意的是,这里没有加-i
参数,代表的是修改的不是原文件,只是把你的操作结果给你打印出来而已。如果你要修改原文件的内容,直接加-i
参数即可(sed通用)。添加后命令如下:
sed -i '3a hello' test.txt
顺便说一下,这里的3a
代表的是在第三行后面添加,那么3i
表示的便是在第三行前面添加。
例7:将hello替换为world
sed 's#hello#world#' test.txt
效果如下:
例8:将每行第一个字母o改为x
sed 's#o#x#' test.txt
效果如下:
如果你想要把所有的o替换成x,那我们就在末尾加一个g
,表示全局替换。
sed 's#o#x#g' test.txt
如果你想吧所有的o和O替换成x,也就是不区分大小写,那么就在末尾加一个I
,表示忽略大小写。
sed 's#o#x#gI' test.txt
3.awk
awk
+ ' '
+文件
操作 | 解释 |
---|---|
{print $1} | 打印第一列 |
{print $1,$2} | 打印第一列和第二列 |
{print $NF} | 打印最后一列 |
“xxx” | 双引号里面添加文字信息 |
NR | 表示行号 |
/xxx/ | 表示查找特定信息 |
~ | 表示查找含有特定信息 |
ps:表格只适用于将下面实例都实操理解后使用。
例1:在test3.txt中打印出第一列
awk '{print $1}' test3.txt
效果如下:
例2:在test3.txt中打印出最后一列
awk '{print $NF}' test3.txt
例3:在test3.txt中打印出第一列和最后一列
awk '{print $1,$NF}' test3.txt
结果如下:
例4 :将第一列和第二列与第三列的乘积结果显示出来
awk '{print $1,$2*$3}' test4.txt
结果如下:
若是要在其中加入文字说明,则可以加" "
:
awk '{print $1,“total:”,$2*$3"$"}' test4.txt
例5:取第一行的数据
awk 'NR==1' test4.txt
效果如下:
NR表示行号的意思,下面列出几个扩展:
NR>5
:表示取出行号大于5的行数据
NR<=5
:表示取出行号小于等于5的行数据
NR<=5 && NR>1
:表示取出行号小于等于5并大于1的行数据
NR==5 || NR<=2
:表示取出行号等于5或小于等于2的行数据
例6:取出含有特定信息的行
awk '/hat/' test4.txt
效果如下:
例7:指定分隔符输出目标结果
awk -F ':' '{print $1}' /etc/passwd
例8:找出第一列数据中有h字母的,并取出第一列和第七列的数据
awk -F ':' '$1~/h/{print $1,$2}' /etc/passwd
我们稍微分解一下:$1~/h/
表示取第一列数据中有h字母的,~
为esc
键下面那个键。
{print $1,$2}
就很简单,就是打印第一列和第二列。
三.进阶阶段
符号 | 解释 |
---|---|
^ | 表示以什么开头 |
$ | 表示以什么结尾 |
^$ | 空行 |
. | 代表任意字符 |
\ | 转义字符 |
* | 重复0次到多次 |
? | 重复0次到多次 |
+ | 重复1次到多次 |
.* | 匹配所有字符 |
^.* | 任意多个字符开头 |
[0,9] | 匹配0和9两个字符 |
{n,m} | 表示n-m位 |
[a-z],[A-Z],[0-9] | 匹配字符集合内任意一个字符 |
[^0-9],[^A-Z],[^a-z] | 不包含数字和字母 |
例1:找出以t开头的行数据
grep '^t' test.txt
效果如下:
若我们要找出不是以t开头的行数据,我们就可以加一个-v
参数,意思是取反。
grep -v '^t' test.txt
例2:找出以cp结尾的行数据
grep 'cp$' test.txt
效果如下:
例3:删除所有的空行
sed '/^$/d' test.txt
之前我们记录sed的时候,也说了这里的删除并不是删除原文件的内容,而是将处理好的结果打印出来给你看。所以要删除原文件的所有空行,我们就需要加一个-i
参数:
sed -i '/^$/d' test.txt
例4:找出xia的行数据(x是未知数)
grep '.ia' test.txt
效果如下:
例5:找出含有.ia行数据
若我们要找出含.
的数据,我们需要在.
前面加一个\
。因为.
本身就代表一个字符,\
是转义字符,旨在将特殊意义的字符回归它本来的意义。
grep '\.ia' test.txt
效果如下:
相比于例4,包含lia的行数据就被舍弃了。例4中的.
代表的是一位字符,而例5则是代表普通符号.
例6:删除所有的注释
- 首先,查找所有含注释的行数据
grep '#.*' test1.txt
效果如下:
- 其次,将所有的注释都变成空。也就是删除所有的注释。
sed -i 's/#.*/ /g' test.txt
效果如下:
- 最后,删除所有的空行
sed -i '/^$/' test2.txt
效果如下:
例7:筛选0-9的数字,a-z或A-Z的字母
grep '[0-5]' test1.txt
当然我们还可以将0-9和a-z混合使用,比如我要筛选出0-9和a-f的数据,就可以这么玩:
grep '[0-9a-f]' test2.txt
还有一个值得说的,就是我们若是只要筛选两个数字呢,我们可以这么写:
grep '[2,9]' test1.txt
效果如下:
除此之外,我们还可以搭配^
取反符使用:
- 不要数字
grep '[^0-9]*' test.txt
- 不要小写字母
grep '[^a-z]*' test1.txt
- 不要字母和数字
grep '[^a-zA-Z0-9]*' test1.txt
例8:筛选出7-15位的ip地址的行数据
ip地址范围是:0.0.0.0 – 225.225.225.255 我们可以根据其位数特点来匹配它。我们可以这么写:
grep '[0-9.]{7,15} /var/log/secure
其中{7,15}
表示的匹配[0-9]
数字匹配7-15
次,大致可以理解为匹配7-15位
的数字。我们特意在0-9
后面加了一个.
,更加符合ip地址的格式。
我们还可以跟进一步,如果我们只要它显示出ip地址,我们可以加一个-o
参数。
grep -Eo'[0-9.]{7,15} /var/log/secure
这里的E表示使用正则表达式,其实你会发现没有E也能使用^$
等这些符号。这些特殊符号就是正则表达式。
例9:高阶混合用法
我们可以更加精确的匹配出ip地址:
ip addr | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
如果是理解了例8,这例子也不难理解。例8那样的方式也可以匹配出88888888这样的8位数字,用上述命令就更加贴合ip地址的格式,也就更好的匹配出ip地址了。
当然如果你还想取出登录失败用户的ip地址,可以这么玩:
grep 'Failed password' /var/log/secure | grep -Eo '[0-9]{1,3}\.[0-9]+'
还不够,我们还可以取root用户登录时间:
lastlog|sed -n '/root/p' | grep -Eo '[0-9]{2}:[0-9]{2}:[0-9]{2}'
例10:\d 和[0-9]区别
\d 和 [0-9] 在某种意义上是一样的,都表示输出0-9数字。
区别就在于\d
属于perl
正则,搭配-E
匹配的是d字母
,只有搭配-P
才是匹配数字
。
文章到这里终于结束了,笔记整理不易,请点点收藏和关注。