データブロックから特定の値を抽出する

データブロックから特定の値を抽出する

以下のようにグローバル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値は2桁に制限されます。 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

これは"、行内の4番目に区切られたフィールドのみを取得します。したがって、フィールドには、二重引用符がない限り、必要な数の文字(または必要に応じて数字)を含めることができます。

しかし、ライン全体が欲しいなら、そうする必要はありません。

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>

gcXMLstarletを使用して、次のように属性を持つノードのデータを抽出できます。id82

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]
}}'

<gc type="global"これにより、最大のIDで始まるブロックが印刷されます。</gc>

aすべての行はキーを持つ配列に保存されます。FNR

6番目のフィールドが前のフィールドよりも大きく、行に文字列が含まれている場合、最初のフィールドはifフラグを設定fし、配列キーの開始変数をs次に設定します。FNRid<gc type=\"global\"

次にifフラグをリセットし、行に文字列が含まれていて1の場合は配列キーの終了変数を設定しますeFNR</gc>f

END配列の要素は、キー値がとの間にある場合にのみ印刷されます。ase

答え4

'type="global"' を含む行を grep し、sed を使用して 'id=':' の後の引用符内の値を抽出できます。

$ grep 'type="global"' /tmp/foo | sed -e 's/^.*id="\([0-9]*\)".*$/\1/'
80
81
82
...

関連情報