- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个文件,其中包含以下形式的条目:
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/
我是一名优秀的程序员,十分优秀!