我有一个日志文件trace.log
。在其中我需要grep查找字符串<tag>
和</tag>
中包含的内容。这对字符串有多组,我只需要在最后一组(换句话说,来自日志文件的tail
)之间返回内容。
额外信用:只有当内容包含“testString”时,我才能返回两个字符串中包含的内容?
感谢您的光临。
编辑:搜索参数和包含在不同的行上,大约有100行内容将它们分开。内容就是我追求的......
答案 0 :(得分:33)
使用tac
以相反的方式打印文件,然后使用grep -m1
打印一个结果。背后的外观和前瞻检查<tag>
和</tag>
之间的文本。
tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)'
鉴于此文件
$ cat a
<tag> and </tag>
aaa <tag> and <b> other things </tag>
adsaad <tag>and last one</tag>
$ tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)'
and last one
编辑:搜索参数和包含在不同的行上 大约有100行内容将它们分开。内容就是我的意思 之后...
然后它有点棘手:
tac file | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]};
/<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit};
p' | tac
我们的想法是撤消文件并使用标记p
来检查<tag>
是否已经出现。它将在</tag>
出现时开始打印,并在<tag>
到来时结束(因为我们正在相反地阅读)。
split($0, a, "</tag>"); $0=a[1];
获取</tag>
split($0, a, "<tag>" ); $0=a[2];
获取<tag>
给出这样的文件a
:
<tag> and </tag>
aaa <tag> and <b> other thing
come here
and here </tag>
some text<tag>tag is starting here
blabla
and ends here</tag>
输出将是:
$ tac a | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p' | tac
tag is starting here
blabla
and ends here
答案 1 :(得分:22)
如果像我一样,你无法访问tac,因为你的系统管理员不会打球,你可以试试:
grep pattern file | tail -1
答案 2 :(得分:1)
除了grep之外的另一个解决方案是sed:
tac file | sed -n '0,/<tag>\(.*\)<\/tag>/s//\1/p'
tac file
以相反的顺序打印文件(cat
向后),然后sed
从输入行0
继续到<tag>.*<\tag>
的第一次出现,并将<tag>.*<\tag>
仅替换为<tag>
内的部分。 p
标志打印输出,该输出被-n
抑制。
修改:如果<tag>
和</tag>
位于不同的行,则无效。我们仍然可以使用sed
:
tac file | sed -n '/<\/tag>/,$p; /<tag>/q' | sed 's/.*<tag>//; s/<\/tag>.*//' | tac
我们再次使用tac
向后读取文件,然后第一个sed
命令从第一次出现时读取,并在找到时退出。仅打印中间的行。然后我们将它传递给另一个sed
进程以剥离它们,最后用tac
再次反转这些行。
答案 3 :(得分:0)
perl -e '$/=undef; $f=<>; push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1]' ex.txt
额外信用:任何方式我都可以返回其中包含的内容 仅当内容包含“testString”时才有两个字符串?
perl -e '$/=undef; $f=<>; push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1] if ($a[-1]~=/teststring/);' ex.txt
答案 4 :(得分:0)
一个处理多行的未经测试的 awk:
awk '
BEGIN {retain="false"}
/<\tag>/ {retain = retain + $0; keep="false"; next}
/<tag>/ {keep = "true"; retain = $0; next}
keep == "true" {retain = retain + $0}
END {print retain}
' filename
我们开始阅读文件;当我们点击时,我们开始保持线条。当我们击中时,我们停下来。如果我们击中另一个,我们清除保留的字符串并重新开始。如果您想要所有字符串,请在每个
打印