前言
最近有个需求,核查对比多台网络设备的配置,需要将设备配置文件中的关键信息(比如:设备的带外地址、Loopback地址等)提取出来。
举个例子:
某台设备的配置文件如下,我想查找该设备Loopback0地址:
一个文本文件的话,我们直接用notepad/notepad ++ 直接Ctrl + F
Loopback0
,找到Loopback0
下面2
行即可找到其地址,但是当多个文件时,再一个个找就很麻烦了。
为了方便高效,又懒得用Python
写脚本遍历查找(一是Python
能力有限,逻辑处理复杂,二是当时时间紧急,着急核查配置),想到了用Linux里面的grep
命令直接操作,后面又想到Windows平台有没有类似的命令呢,于是一番查找资料,发现Windows上使用Powershell里面的Select-String
也可以实现类似的功能。
经过实验,都可以完美满足我的需求,现分享给大家。
一、Linux 环境使用 grep
实现需求
Linux环境这里为了方便,没装虚拟机,用的是Cygwin
(Cygwin是一款可以在Windows上模拟Linux环境的工具),只用来练习Linux上面的命令完全够用。
grep
命令就不多说了,Linux 平台上很强大的查找命令,参数很多,详细参数可输入 grep --help
查看命令使用帮助,更详细的使用方法可 man grep
查看 。这里只介绍和我的需求相关的两个参数:
-
-A
打印后面 n 行上下文, n是参数
-
-B
打印前面 n 行上下文,n是参数
我的需求其实很简单,还是以查找Loopback0
地址为例,直接用grep -A
命令查看上下文几行就满足了。
- 防止出现干扰项,关键字加上正则
^
, 表示查找以interface LoopBack0
开头的文本,我们只要关键字后面2行的上下文内容,因此参数就是-A 2
,后面直接跟关键字和文件路径,这里的话文件就在当前目录下,因此直接写文件名(可用通配符过滤);
grep -A 2 "^interface LoopBack0" *S6800*.xml
- 这样,我们的需求其实已经基本满足了,下一步我们取出ip地址所在行的内容,只需要再
grep
一次 ip address
关键字即可。
grep -A 2 "^interface LoopBack0" *S6800*.xml | grep "ip address"
- 更进一步,使用
awk
分割字符(用了两次awk -F
,应该还有更简洁的实现方式),只输出文件名称和ip地址:
grep -A 2 "^interface LoopBack0" *S6800*.xml | grep "ip address" | awk -F '-' '{print $1 $2 $3}' | awk -F ' ' '{print $1" "$4}'
- 把结果输出到文本文件,方便后续处理:
grep -A 2 "^interface LoopBack0" *S6800*.xml | grep "ip address" | awk -F '-' '{print $1 $2 $3}' | awk -F ' ' '{print $1" "$4}' >> loopback0.txt
至此,我们的需求已经实现,后续把文本文件里面的内容,复制到excel,使用分列等方式提取ip地址,核查对比就很方便了。
二、Windows 环境使用powershell 内置命令Select-String
实现需求
Windows平台上实现思路其实和Linux上使用grep
思路一致,无非就是找到一个grep
命令的替代品。一开始找的是cmd环境中的findstr
命令,通过查找资料和实验发现很难实现我的需求,因此又经过一番搜索,选择了powershell环境下的Select-String
命令。
这里贴一下Select-String
的官方说明:
Select-String
更详细的使用方法和示例,详见微软官方文档,链接如下:
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/select-string?view=powershell-7.2
针对我们的需求,使用Select-String
主要涉及以下几个参数:
-
-Path
文件路径;
-
-Pattern
要查找的关键字;
-
-Context m,n
打印上下文内容,m表示打印前面 m 行,n表示打印后面n行
在文件所在目录地址栏,输入powershell
即可在当前目录打开powershell命令行(和cmd类似,无需cd
进入目录)
- 输入如下命令,查找内容,这里和上面一样,无非就是
-Context
参数,我们第一个写0,不需要打印前面的行,第二参数写2,打印后面2行,其他参数关键字和grep
中一致;
Select-String -Path *S6800*.xml -Pattern "^interface LoopBack0" -Context 0,2
powershell 返回结果中默认还会输出行号,grep
默认不会,不过grep
中可以添加-n
参数输出行号,示例如下:
grep -n -A 2 "^interface LoopBack0" *S6800*.xml
- 取出ip地址所在行的内容,这里像
grep
一样直接grep "ip address"
关键字是不行的,需要使用Out-String
把上次查找的结果作为输入对象转成字符串再进行Select-String
。
Select-String -Path *S6800*.xml -Pattern "^interface LoopBack0" -Context 0,2 | Out-String -Stream | Select-String -Pattern "ip address"
关于Out-String
,这里也贴个官方说明和文档链接:
Out-String
官方链接:
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/out-string?view=powershell-7.2
- 把结果输出到文本文件,方便后续处理(这里没有再深入研究powershell 切割字符,提取文件名和ip地址,应该有和
Python split()
或者Linux awk
类似的函数或者命令):
Select-String -Path *S6800*.xml -Pattern "^interface LoopBack0" -Context 0,2 | Out-String -Stream | Select-String -Pattern "ip address" >> loopback0-win.txt
同样的,在Windows上使用powershell也实现了我们的需求。
三、思路拓展
- 之前的话,提取设备配置的特定关键信息,我一直使用
Python
编写代码脚本,通过遍历文本内容查找关键信息并输出到excel文件,逻辑处理上稍微复杂。
- 无论是Linux平台的
bash shell
环境还是Windows平台的powershell
环境,都不仅仅是用几个命令实现需求,后续对于这些关键信息的简单提取,可以将其分类,做成shell
脚本或者powshell
脚本,这个后面有时间的话再拓展更新一下。
- 针对设备配置中,一些比较复杂的关键信息提取&对比&核查,需要进行多次逻辑处理的,可继续使用
Python
来实现,输出到Excel文件;
- 针对设备配置中,一些比较简单的关键信息提取,可使用Linux平台的
grep + awk
等命令、Windows Powershell平台的Select-String
等命令,以脚本的形式,输出到文本文件;
四、参考链接
https://qa.1r1g.com/sf/ask/2860463231/#
https://stackoverflow.com/questions/40863760/windows-findstr-how-to-print-3-lines-before-and-after-matched-lines
https://stackoverflow.com/questions/49386054/how-can-i-filter-out-text-twice-in-powershell
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/select-string?view=powershell-7.2
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/out-string?view=powershell-7.2