在文件中,查找某个关键字时如何打印关键字上下文:比如 关键字前后3行?Windows Powershell select-string 、Linux grep -A -B

2023-11-16

前言

最近有个需求,核查对比多台网络设备的配置,需要将设备配置文件中的关键信息(比如:设备的带外地址、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是参数
    grep我的需求其实很简单,还是以查找Loopback0地址为例,直接用grep -A 命令查看上下文几行就满足了。
  1. 防止出现干扰项,关键字加上正则^, 表示查找以interface LoopBack0开头的文本,我们只要关键字后面2行的上下文内容,因此参数就是-A 2,后面直接跟关键字和文件路径,这里的话文件就在当前目录下,因此直接写文件名(可用通配符过滤);

grep -A 2 "^interface LoopBack0" *S6800*.xml
grep -A

  1. 这样,我们的需求其实已经基本满足了,下一步我们取出ip地址所在行的内容,只需要再grep 一次 ip address关键字即可。

grep -A 2 "^interface LoopBack0" *S6800*.xml | grep "ip address"
grep -A | grep

  1. 更进一步,使用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 | grep | awk -F

  1. 把结果输出到文本文件,方便后续处理:

grep -A 2 "^interface LoopBack0" *S6800*.xml | grep "ip address" | awk -F '-' '{print $1 $2 $3}' | awk -F ' ' '{print $1" "$4}' >> loopback0.txt
grep -A | grep | awk -F  >> test.txt

至此,我们的需求已经实现,后续把文本文件里面的内容,复制到excel,使用分列等方式提取ip地址,核查对比就很方便了。

二、Windows 环境使用powershell 内置命令Select-String 实现需求

Windows平台上实现思路其实和Linux上使用grep思路一致,无非就是找到一个grep命令的替代品。一开始找的是cmd环境中的findstr命令,通过查找资料和实验发现很难实现我的需求,因此又经过一番搜索,选择了powershell环境下的Select-String命令。

这里贴一下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进入目录)

  1. 输入如下命令,查找内容,这里和上面一样,无非就是-Context 参数,我们第一个写0,不需要打印前面的行,第二参数写2,打印后面2行,其他参数关键字和grep中一致;

Select-String -Path *S6800*.xml -Pattern "^interface LoopBack0" -Context 0,2
select-string
powershell 返回结果中默认还会输出行号,grep默认不会,不过grep中可以添加-n 参数输出行号,示例如下:
grep -n -A 2 "^interface LoopBack0" *S6800*.xml
grep -n -A

  1. 取出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"
select-string | out-string | select-string

关于Out-String,这里也贴个官方说明和文档链接:
Out-String
Out-String官方链接:
https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/out-string?view=powershell-7.2

  1. 把结果输出到文本文件,方便后续处理(这里没有再深入研究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
    select-string | out-string | select-string >> test.txt

同样的,在Windows上使用powershell也实现了我们的需求。

三、思路拓展

  • 之前的话,提取设备配置的特定关键信息,我一直使用Python编写代码脚本,通过遍历文本内容查找关键信息并输出到excel文件,逻辑处理上稍微复杂。
  • 无论是Linux平台的bash shell环境还是Windows平台的powershell环境,都不仅仅是用几个命令实现需求,后续对于这些关键信息的简单提取,可以将其分类,做成shell脚本或者powshell脚本,这个后面有时间的话再拓展更新一下。
  1. 针对设备配置中,一些比较复杂的关键信息提取&对比&核查,需要进行多次逻辑处理的,可继续使用Python来实现,输出到Excel文件;
  2. 针对设备配置中,一些比较简单的关键信息提取,可使用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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在文件中,查找某个关键字时如何打印关键字上下文:比如 关键字前后3行?Windows Powershell select-string 、Linux grep -A -B 的相关文章

  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • 如何在 Windows 下向 .sh 脚本传递参数?

    我正在尝试在 Windows 下执行 sh 脚本 我安装了 Git 它允许我执行 sh 文件 但是 如果不使用 sh 作为执行前缀 我似乎无法传递任何参数 我的 sh 文件 echo Test 1 如果我用以下命令执行它 gt sh tes
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • Linux:如何从特定端口发送TCP数据包?

    如何打开原始套接字以从特定 TCP 端口发送 我希望所有连接始终来自临时端口以下的一系列端口 如果您正在使用raw套接字 然后只需在数据包标头中填写正确的 TCP 源端口即可 相反 如果您使用 TCP 套接字接口 socket connec
  • 安装J语言的JQt IDE,出现错误

    我一直按照这里的说明进行操作 http code jsoftware com wiki System Installation Linux http code jsoftware com wiki System Installation L
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • 用于推送通知的设备令牌

    我正在实施推送通知服务 我需要创建一个数据库来存储 4 个移动平台的所有设备令牌 我想根据他们的平台 iOS Android BlackBerry WP7 来组织它们 但是有什么方法可以区分平台 这样如果我只想向 Android 用户发送消
  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少
  • 在 64 位 Windows 上运行 32 位可执行文件时出现问题

    如果允许的话 我会添加 500 个我自己的代表作为赏金 我在用着wkhtml转pdf http wkhtmltopdf org 将 HTML 网页转换为 PDF 这在我的 32 位开发服务器上完美运行 不幸的是 我无法运送我的机器 p 但是
  • 在 Windows 上通过 ctypes 将文件描述符传递给 C 库函数

    我试图通过 ctypes 将文件描述符传递给在 fd 上执行写入的 C 函数 在linux上它可以工作 在 Windows 上则不然 我不明白为什么 我没有 Windows 开发人员的经验 C func signature void fun
  • 使用 Visual C++ 在桌面上绘图

    我正在编写一个 opencv 应用程序 使用 Visual Studio VC 控制台应用程序使用激光束进行绘图 我想在桌面上画线 我知道绘图功能在 GDI32 dll 中可用 但对如何将 GDI32 dll 与我的 vc 代码集成感到困惑
  • docker容器大小远大于实际大小

    我正在尝试从中构建图像debian latest 构建后 报告的图像虚拟大小来自docker images命令为 1 917 GB 我登录查看尺寸 du sh 大小为 573 MB 我很确定这么大的尺寸通常是不可能的 这里发生了什么 如何获
  • 如何将 Hudson/Jenkins 参数传递给 Windows 批处理命令

    好吧 我需要在我的 Hudson 作业中执行一个批处理文件 我有一个参数 Jenkis 参数 我需要将这个值 如参数 传递给批处理文件 我尝试了以下操作 Deploy cmd configuration DEPLOYCONFIGURATIO
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute

随机推荐