gpt4 book ai didi

Bash 脚本,用于选择以跨越两行的模式开始并以空行结束的范围。赛德?

转载 作者:行者123 更新时间:2023-11-29 09:30:45 25 4
gpt4 key购买 nike

我有一个文件,其中包含以下形式的条目:

2012-01-12 22:20:21,638 INFO  [Tracer]
something.of.interest
...some number of additional lines...
<<a blank line>>
...other stuff...

我只想挑出第一行包含 [Tracer] 并且第二行包含 something.of.interest 的文本 block ,以空白行结尾未知行数第二行。无法更改文件格式。

我可以使用 sed 通过执行类似以下操作来挑选出整个 block :

gsed -n '/^[0-9]\{4\}[^\[]*\[Tracer\]/,/^$/ p' /path/to/file/to/parse

这会按预期选择整个 block ,但它会匹配第二行不包含 something.of.interest 的条目。

我可以使用 N 获取下一行,然后匹配当前行和下一行,并且只有当我看到 [Tracer] 和 something.of.interest 被\分隔时,我才能选择前两行n,但是在我换行之前,我似乎无法弄清楚如何获取以下行。在伪 sed 中我想做这样的事情:

/look for Tracer line 1/{
N
/look for \n.*something.of.interest/
},
/look for blank line for end of range/
p

遗憾的是这实际上不起作用,通常我会收到“未知命令”消息。

有没有一种方法可以使用开始和结束可以是多行模式的模式在 sed 中定义范围?

该解决方案最终需要在 Solaris 5.10 上运行。 GNU sed (gsed) 可用,awk 也可用,如果在这种情况下这是更好的选择的话。

非常感谢您的建议。

更新

我似乎可以在 awk 中做到这一点,尽管结果有点可怕。我非常想要一个更优雅的解决方案,这里仍然供引用是一个 awk 脚本,它将找到感兴趣的行:

1) 创建一个文件 something.awk,其中第一行是匹配第 1 行的正则表达式:

/\[Tracer\]/ {
l1=$0
if (getline <= 0) {
print "getline failed"
exit 1
}
if (index($0, L2MARKER) > 0) {
print l1
print $0
stop=0
while(stop != 1) {
if (getline <= 0) {
print "getline failed :( ERRNO:" + ERRNO
exit 1
}
print;
if (length($0) == 0) {
stop = 1
}
}
}
}

2) 从 shell 调用类似于 awk -f something.awk L2MARKER='something.of.interest' the.file.to.parse

最佳答案

编辑:有人注意到我的第一个解决方案有点不对劲。这是修复的尝试,但由于缺少测试它的地方,我还没有测试它。

我在 sed 中提出了一些可能对您有用的东西:

/Tracer/ { N; /interesting/ { h; :a; n; H; /^$/! ba; g; p } }

下面是解释!

给定一个这样的测试文件:

boring
boring
awesome [Tracer]
interesting
totally interesting
and awesome
still interesting
very interesting

back to boring
awesome [Tracer]
Nah just kidding
nope

darn

上面的命令扩展为以下内容,并附有解释:

/Tracer/ {          # Looks for Tracer
N # Moves on to the next line
/interesting/ { # Looks to see if "interesting" is in the next line
h # Put first two lines in hold space
:a # Label "a"
n # Move on to next line
H # Appends line to hold space
/^$/! ba # If not a blank line, branch back to "a"
g # Put the hold space into the pattern space
p # Print the pattern space
}
}

而且,应该这样做:

sed -n '/Tracer/ { h; n; /interesting/ { :a; H; n; /^$/! ba }; g; p }' file.txt
awesome [Tracer]
interesting
totally interesting
and awesome
still interesting
very interesting
[blank line]

[blank line] 是字面上的空白行,但我无法在此处的代码块中表达它。显然,您可以很容易地修改 /Tracer//interesting/ 的正则表达式,具体取决于行的具体内容。

关于Bash 脚本,用于选择以跨越两行的模式开始并以空行结束的范围。赛德?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8843495/

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