3

システムのステータスを日付別に保存する記録ファイルがあります。それを生成するスクリプトは cron 経由で実行されるため、ファイルは常に長くなります。すべての行を反復して処理するスクリプトを作成しましたが、これには非常に長い時間がかかりました。awk は大きなテキスト ファイルの処理がはるかに高速であると聞いたことがあります。私の問題は、私がそれを使ったことがないということです。awk を使用して、日付範囲内のすべてのエントリを取得することは可能ですか? 日付は で作成されたので、すべて秒単位date +%sです。これは、範囲内のデータをすばやく見つけられるようにしたい出力の例です。たとえば、最初の列が 1344279903 と 1344280204 の間にあるすべての行を取得するにはどうすればよいでしょうか?

1344279903 |  0  | 0 | node  |  1
1344279904 |  0  | 0 | node  |  2
1344279905 |  0  | 0 | node  |  3
1344280202 |  0  | 0 | node  |  1
1344280203 |  0  | 0 | node  |  2
1344280204 |  99  | 0 | node  |  3
4

3 に答える 3

4

次のような条件式を使用できます。

awk '$1 >= 1344279903 && $1 <= 1344280204 { print $0 }' data.txt
于 2012-08-06T19:18:00.040 に答える
3

awkで?

awk -F'|' '1344279903 <= $1 && $1 <= 1344280204' file

シード付き?

sed -n '/1344279903/,/1344280204/p' file

最後の print ステートメントの後で明示的に終了することで、awk 式をさらに効率的にすることができます。

awk -F'|' '1344279903 <= $1 && $1 <= 1344280204{ print $0; } $1 == 1344280204{ exit; }' file
于 2012-08-06T19:20:11.303 に答える
2

これに対する私の見解は次のとおりです。

#!/usr/bin/awk -f

BEGIN {
  start=ARGV[1]; ARGV[1]="";
  end=ARGV[2]; ARGV[2]="";
}

$1 < start { next }

$1 > end { exit }

1

これはどのように作動しますか?

Awk は、入力の各行に適用される一連の「条件 { コマンド }」ブロックを使用します。BEGIN ブロックは、入力が開始される前に実行される「魔法の」ブロックです。(入力の最後に同様の END ブロックがありますが、ここでは使用しません。)

  • このスクリプトでは、BEGIN ブロックがコマンド ラインに基づいて「開始」変数と「終了」変数を設定し、これらの変数を空にして、awk がそれらを入力ファイルとして解釈しようとしないようにします。
  • 次の条件により、awk は開始日の前に発生するすべての行をスキップします。を実行するnextと、awk に新しい入力行を読み取り、その条件の処理を最初からやり直すように指示します。
  • 次の条件により、印刷する日付の範囲の最後に到達すると awk が終了します。(もちろん、これは入力データが時系列であることが前提です。)
  • 最後の条件は、それ自体が「1」です。これは、「現在の行を印刷する」の Awk 省略形であり、前の条件のいずれも満たされない場合に実行されます (前の条件の両方がスクリプトのこのポイントに到達することを妨げるため)。

サンプルデータでの動作は次のとおりです。

ghoti@pc$ ./awkdate 1344279905 1344280203 data.txt
1344279905 |  0  | 0 | node  |  3
1344280202 |  0  | 0 | node  |  1
1344280203 |  0  | 0 | node  |  2
ghoti@pc$ 
于 2012-08-06T19:33:05.883 に答える