我有由全局 ID 区分的数据块,如下所示。我需要提取具有最高 id 值的最后一个数据块,在下面的示例中,id="82"
.
<gc type="global" id="80" totalid="80" intervalms="315080.595">
---Remaining data---------
</gc>
<gc type="global" id="81" totalid="81" intervalms="315080.595">
---Remaining data---------
</gc>
<gc type="global" id="82" totalid="82" intervalms="315080.595">
---Remaining data---------
</gc>
我可以执行以下操作。但是,它将限制 id 值只能为两位数。如何在不对 id 值施加数字限制的情况下导出最后一个数据块。
data1=`grep "gc type="global"" abc.log| cut -c24-26|tail -n1`
lastdata="gc type="global"=$data1"
sed -n '/'"${lastdata}"'/,$p' abc.log>last_block_data.log
答案1
您不必cut
按-c
字符计数。相反,您可以cut
使用指定的-d
限制符。
grep '^<gc type="global"' <infile | cut -d\" -f4
80
81
82
这只得到"
一行中的第四个分隔字段。因此,该字段可以是任意数量的字符(如果您愿意,也可以是数字),只要它们都不是双引号即可。
但如果你想要整条线,你也不必这样做。
sed -e'/^<gc type="global"/!{g;/./q;d;}' -e'h;$!d' <infile
答案2
假设数据是格式正确且结构良好的 XML 文档,如下所示
<?xml version="1.0"?>
<root>
<gc type="global" id="80" totalid="80" intervalms="315080.595">
---Remaining data---------
</gc>
<gc type="global" id="81" totalid="81" intervalms="315080.595">
---Remaining data---------
</gc>
<gc type="global" id="82" totalid="82" intervalms="315080.595">
---Remaining data---------
</gc>
</root>
可以使用 XMLstarlet 提取属性为 的gc
节点的数据,如下所示:id
82
xmlstarlet sel -t -v '//gc[@id="82"]' file.xml
这将获取相关节点的内容gc
,无论该节点恰好位于文档中的哪个位置。
答案3
awk -F[=\"] '{
a[FNR]=$0;
if ($6>l && $0 ~ "<gc type=\"global\""){
l=$6;f=1;s=FNR
};
if($0 ~ "</gc>" && f==1 ){
e=FNR;f=0
}}
END{
for (i=s;i<=e;i++) {
print a[i]
}}'
这将打印从具有最大 id<gc type="global"
开始 的块。</gc>
所有行都保存到数组中,a
键为FNR
如果第 6 个字段大于前一个字段并且该行包含 string ,则第一个if
将设置标志f
并将数组键开始变量设置s
为。FNR
id
<gc type=\"global\"
接下来if
重置标志并将数组键结束变量设置e
为FNR
如果该行包含字符串</gc>
且f
等于 1
仅当键值在和之间时才会打印END
数组中的元素。a
s
e
答案4
您可以 grep 查找带有 'type="global"' 的行,然后使用 sed 提取 'id=':' 之后引号内的值
$ grep 'type="global"' /tmp/foo | sed -e 's/^.*id="\([0-9]*\)".*$/\1/'
80
81
82
...