次のテキストファイル(区切り文字としてスペースを含む)があります。
Date Time---------OtherFields-------Source IP Destination IP
2014-11-24 12:58:59.290 1.2.3.4 5.6.7.8
2014-11-24 12:59:01.402 1.2.3.8 5.6.7.8
2014-11-24 13:00:01.542 12.14.25.1 5.6.7.8
2014-11-25 14:00:02.5 12.14.25.2 5.6.7.8
2014-11-25 15:00:01.542 12.14.25.1 6.7.8.9
2014-11-25 16:00:01.542 12.14.25.5 6.7.8.9
宛先IP 5.6.7.8の場合は、最新の日付と時刻を持つ行を選択し、さらに処理するために新しいテキストファイルに保存したいと思います。他のすべての宛先IPアドレスにも同様に適用されます。こんなラインがたくさんあります。
これ希望の出力そうです。
2014-11-25 14:00:02.5 12.14.25.2 5.6.7.8
2014-11-25 16:00:01.542 12.14.25.5 6.7.8.9
私はロジックを持っていません。どんな助けでも大変感謝します。ありがとう
答え1
for dest in $(awk '{print $NF}' mylogfile | sort | uniq)
do
grep ${dest} mylogfile | sort -k1 -k2 | tail -1
done
1 $(awk '{print $NF}' mylogfile | sort | uniq)
ログファイルの各行の最後のフィールド(ターゲットIP)を印刷します。同じIPアドレスが連続したブロックになるように並べ替えます。 uniq は同じラインブロックのインスタンスを 1 つだけ印刷します。
2 & 4 do ... done
これは自明だと思います。一般的なループ構造
3 grep ${dest} mylogfile | sort -k1 -k2 | tail -1
IPアドレスが1つの行を見つけるには(IPアドレスが最後のフィールド以外のフィールドで繰り返されないと仮定する)、最初にフィールド1を並べ替えてから、最新の日付/タイムスタンプを含むフィールド2を並べ替えます。最後の行を入力してください。tail -1
最後の行をつかむ
答え2
次のことを試すことができますawk
。
awk '{ x = $1" "$2; if (x > a[$4]) { a[$4] = x; b[$4] = $0; } } END { for (i in b) { print b[i]; } }' file
しかし、メモリには2つの配列があるため、非常に大きなファイルにはあまり役に立ちません。