我有一个日志文件trace.log
。在其中,我需要对字符串中包含的内容进行 grep<tag>
和</tag>
. 这对字符串有多组,我只需要返回最后一组之间的内容(换句话说,来自tail
日志文件的)。
额外积分:只有当内容包含“testString”时,我才能返回包含在两个字符串中的内容?
感谢您的关注。
编辑:搜索参数 和 包含在不同的行中,大约有 100 行内容将它们分开。内容是我要的...
用于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
如果像我一样,您无法访问 tac,因为您的系统管理员不会玩球,您可以尝试:
grep pattern file | tail -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
进程以去除 's,最后再次使用tac
.
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
一个处理多行的未经测试的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
我们开始只是读取文件;当我们点击 时,我们开始保持线条。当我们击中 时,我们停止。如果我们点击另一个,我们清除保留的字符串并重新开始。如果你想要所有的字符串,在每个打印