gpt4 book ai didi

bash - 如何找到一个字符串以及给定字符串的上下行数

转载 作者:行者123 更新时间:2023-12-02 09:03:22 26 4
gpt4 key购买 nike

我使用 grep 查找一个字符串以及该字符串上下的不确定行数,直到匹配双换行。例如,在一个文档中我有这样的内容:

Name: Alice
ID: 6969
Interests: foo,bar

Name: Bob
ID: 5555
Interests: foo,bar
Experience

Name: Carl
ID: 3236
Interests: foo,bar

我想通过ID查找有关一个人的所有信息,所以如果我查找5555,我想要的输出是:

Name: Bob
ID: 5555
Interests: foo,bar
Experience

我尝试过使用grep -C n ID_string(其中n是与给定字符串匹配的上下行数),但输出是固定的行数“n”并且我想要直到双断线。任何想法?谢谢。

最佳答案

这可能对你有用(GNU sed):

sed -n '/\S/{h;:a;n;//{H;$!ba};g;/5555/p}' file

关闭隐式打印-n

当当前行包含非空格字符时,在保留空间中开始行集合。

在空行或文件末尾结束集合。

测试集合中是否有所需的字符串,如果匹配则打印整个集合。重复。


要向结果添加换行符,请使用:

sed -n '/\S/{h;:a;n;//{H;$!ba};z;H;g;/5555/p}' file

Sed 是一个流编辑器。它用于编辑文本文件,通常一次处理一行文本。它有两个缓冲区用于完成此任务。模式空间 (PS) 和称为保持空间 (HS) 的备用缓冲区。正常的事件流程是 sed 将一行文本读入 PS 并删除其换行符。 Sed 指令(命令)作用于 PS,重新附加剥离的换行符,并将结果传递到标准输出,即打印出来。

-n 选项关闭将 PS 传递到 stdout 的隐式性质,即如果您想打印某些内容,则必须发出命令才能执行此操作,例如 pP 打印 PS 或打印 PS 的第一行。

Sed 使用正则表达式来决定是否将命令应用于 PS。 /\S/ 是一个正则表达式,用于测试 PS 中是否有任何非空白字符。 Sed 使用括号对命令进行分组,命令之间用分号分隔。

h 命令用 PS 的内容替换保留空间 (HS) 中的任何内容。

Sed 可以执行循环。它通过定义要循环的占位符和中断循环占位符的命令来实现此目的。 :a 定义了一个名为 a 的循环占位符,b 是命令的中断。

n 命令将下一行提取到 PS 中。通常这会导致 PS 的内容在被替换之前被推送到 stdout,但由于 -n 选项处于打开状态,因此其内容会被丢弃。

// 是之前正则表达式的简写,即现在再次测试 PS 的内容是否为非空白字符,如果是,则执行括号内的命令。在这种情况下,H 将 PS 附加到 HS,并用之前删除的换行符分隔。

Sed 知道每行的行号,也知道文件的最后一行何时出现在 PS 中。 $ 表示最后一行。 ! 是 not 命令,它否定先前的地址或正则表达式,例如$! 表示不是文件的最后一行。将它们放在一起 $!ba 意味着,如果它不是文件的最后一行,则将 b 中断到占位符 a。因此,命令流被定向回 :a 并且 sed 从那里恢复处理。

如果 // 不匹配,则推断两种可能性,当前行为空或它是文件的最后一行。 z zaps PS 并将其清空。 H 将空行附加到由换行符分隔的 HS。

g 将 PS 替换为 HS 的内容。循环所建立的行集合现在位于 PS 中。另一个正则表达式尝试匹配 PS /5555/,如果是,则发出 p 命令来打印 PS。

因此,sed 程序会遍历文件,收集 HS 中的非空行集合,并在正则表达式匹配时打印它们。

关于bash - 如何找到一个字符串以及给定字符串的上下行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61288416/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com