0

誰かが問題を解決するのを手伝ってくれることを願っています。sed を使用したファイルの読み取りに関する多くのトピックを見つけましたが、私のケースには当てはまりません。誰かが次の状況の解決策を知っているかもしれません:

定義されたサイズ (私の場合は 5MB) のファイルを作成するロガーがあります。ロガーはファイルをリング バッファーのように使用し、ロガー情報をこのファイルに書き込みます。もちろん、ロガーは 1 行目から開始し、最後に eof を付けます。16 進エディタでは、次のようになります。

0d 3c 3c 3c 45 4f 46 3e 3e 3e 0d 20 20 20 20 20  .<<<EOF>>>.

簡単な状況と複雑な状況の 2 つの状況があります。

  1. 最初から最後の識別子まで印刷する必要があります。

  2. 最も美しいソリューションは、EOF の後に初期値 (0x20) があるかどうかを認識し、1 行目から EOF までを出力します。行末識別子の後に値がある場合は、EOF の後、ファイル サイズまですべてを読み取り、次に 1 行目から EOF 識別子までを読み取ります。これにより、この「リング バッファ」のすべての行が出力されます。このようなことは可能ですか?

(1)を解決するために、いくつかのsedコマンドを試しました。

sed -e '1,$p' test.log > result.txt 

-> 目的: 1 行目から EOF パターンまですべてを出力しますが、両方のファイルのサイズは同じです (私の場合は 5MB)。$p は、EOF パターンではなく、実際のファイルの終わりを参照しているようです。

sed -e '/EOF/,$d' test.log > result.txt 

-> 目的: EOF パターンの前のすべてを出力しますが、result.txt のサイズは 0 です。

これを解決するためのヒントや解決策を提供できる人はいますか?

4

1 に答える 1

0

を使用するsedと、2 つのコマンド (およびファイルの 2 つのスキャン) が必要になると思います。

logfile="…some-name…"
eofmark="<<<EOF>>>"

sed -n "/$eofmark/,\$ { /$eofmark/d; p; }" $logfile  # Read the tail material
sed -n "1,/$eofmark/  { /$eofmark/d; p; }" $logfile  # Read the head material

perlまたはを使用するawkと、ファイル全体をメモリに丸呑みしてから、テール部分とヘッド部分を出力できます。たとえば、awk次のようになります。

logfile="…some-name…"
eofmark="<<<EOF>>>"

awk "/$eofmark/"' {eofline = NR}
     {line[NR] = $0}
     END { for (i = eofline+1; i <= NR; i++) print line[i]
           for (i = 1; i < eofline; i++) print line[i]
     }' $logfile

5 MiB のファイルをメモリに読み込んでも、ギガバイトのメイン メモリを搭載したマシンに負荷がかからないため、これは実現可能です。ファイル自体が数ギガバイトのデータである場合、それをメモリに丸呑みすることについてよく考えなければなりませんが、2 回スキャンするのも面倒です。

于 2014-12-15T08:17:30.830 に答える