1

行が X 文字を超える場合、システムはログ ファイル内の行を折り返します。ログからさまざまなデータを抽出しようとしていますが、最初にすべての分割行を結合して、gawk がフィールドを単一のレコードとして解析できるようにする必要があります。

例えば:

2012/11/01 field1 field2 field3 field4 fi
eld5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 field3 field4 fi
eld5 field6 field7 field8 field9 field10 
field11 field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4

帰りたい

2012/11/01 field1 field2 field3 field4 field5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4

私の場合、実際の最大行長は 130 ですgetline。ちょうど 130 文字の長さのエントリがある場合に備えて、その長さをテストして次の行に結合するために使用するのは気が進まないです。

ログ ファイルをクリーンアップしたら、関連するすべてのイベントを抽出する必要もあります。「関連性」には、次のような基準が含まれる場合があります。

  • 「foo」は、レコード内の任意のフィールドのどこにでもあります
  • field2 ~ /bar|dtn/
  • if field1 ~ /xyz|abc/ && field98 == "0001"

2 つの連続した gawk プログラムを実行する必要があるかどうか、またはこれらすべてを 1 つに結合できるかどうか疑問に思っています。

私は gawk の初心者で、Unix 以外の出身です

4

6 に答える 6

2

これはうまくいくかもしれません(GNU sed):

sed -r ':a;$!N;\#\n[0-9]{4}/[0-9]{2}/[0-9]{2}#!{s/\n//;ta};P;D' file
于 2013-02-08T23:20:26.833 に答える
2
gawk '{ gsub( "\n", "" ); printf $0 RT }
    END { print }' RS='\n[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]' input

これは、次の方法でいくらか単純化できます。

gawk --re-interval '{ gsub( "\n", "" ); printf $0 RT }
    END { print }' RS='\n[0-9]{4}/[0-9]{2}/[0-9]{2}' input
于 2013-02-08T20:36:13.260 に答える
2
$ awk '{printf "%s%s",($1 ~ "/" ? rs : ""),$0; rs=RS} END{print ""}' file
2012/11/01 field1 field2 field3 field4 field5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11  field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4

再結合されたレコードを実際に印刷するだけではないことに気付いたので、再コンパイルされたレコードでテストしやすい別の方法を次に示します (このスクリプトの「s」:

$ awk 'NR>1 && $1~"/"{print s; s=""} {s=s $0} END{print s}' file

この構造を使用すると、単に s を出力する代わりに、たとえば s に対してテストを実行できます (3 番目のレコードの「foo」に注意してください)。

$ cat file
2012/11/01 field1 field2 field3 field4 fi
eld5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 foo field4 fi
eld5 field6 field7 field8 field9 field10
field11 field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4

$ awk '
function tst(rec,     flds,nf,i) {
   nf=split(rec,flds)
   if (rec ~ "foo") {
      print rec
      for (i=1;i<=nf;i++)
         print "\t",i,flds[i]
   }
}
NR>1 && $1~"/" { tst(s); s="" }
{ s=s $0 }
END { tst(s) }
' file
2012/12/31 field1 field2 foo field4 field5 field6 field7 field8 field9 field10 field11 field12 field13
         1 2012/12/31
         2 field1
         3 field2
         4 foo
         5 field4
         6 field5
         7 field6
         8 field7
         9 field8
         10 field9
         11 field10
         12 field11
         13 field12
         14 field13
于 2013-02-09T00:16:19.387 に答える
1

これはあなたのために働くかもしれません:

awk --re-interval '/^[0-9]{4}\//&&s{print s;s=""}{s=s""sprintf($0)}END{print s}' file

あなたの例でテストしてください:

kent$  echo "2012/11/01 field1 field2 field3 field4 fi
eld5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 field3 field4 fi
eld5 field6 field7 field8 field9 field10 
field11 field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4"|awk --re-interval '/^[0-9]{4}\//&&s{print s;s=""}{s=s""sprintf($0)}END{print s}'
2012/11/01 field1 field2 field3 field4 field5 field6 field7
2012/11/03 field1 field2 field3
2012/12/31 field1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12 field13
2013/01/10 field1 field2 field3
2013/01/11 field1 field2 field3 field4
于 2013-02-08T20:48:41.230 に答える
1

これは、追加のフィルタリングも処理する少し大きな Perl ソリューションです (このperlにもタグを付けたように)。

root@virtualdeb:~# cat combine_and_filter.pl 
#!/usr/bin/perl -n 

if (m!^2\d{3}/\d{2}/\d{2} !){
    print $prevline if $prevline =~ m/field13/;
    $prevline = $_;
}else{
    chomp($prevline);
    $prevline .= $_
}


root@virtualdeb:~# perl combine_and_filter < /tmp/in.txt
2012/12/31 field1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12 field13
于 2013-02-08T20:45:50.183 に答える
0

これを実現するための非常に短いスクリプトを次に示します。

sed '/^[[:digit:]]/ { :r N; /\n\([^[:digit:]]\)/ s:: \1:g; tr; } ' FILE

この形でよろしいですか?

于 2013-02-08T20:58:54.383 に答える