AWKパターンに続く行を除く特定の行をフィルタリングする方法

AWKパターンに続く行を除く特定の行をフィルタリングする方法

次の構造のログファイルがあります。

  1. タイムスタンプヘッダ
  2. ログ行

これらのファイルの例は次のとおりです。

Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: ---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: positionX: 141 positionY: 39
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: ---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: positionX: 141 positionY: 39

次のタイムスタンプを除くすべてのタイムスタンプを削除したいと思います。---

---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39

私はこれを試しました:

cat logFile.txt | awk -F':' '/$2=="---"/ {next; print $0; continue}; !/^FINE/ {next}; {print}'

成功しませんでした。

私はFreeBSD 12.1を使用しています(csh、しかし正しいツールが間違っているので問題はないようです。私が間違っている場合は修正してください)。

答え1

sedは次のことができます。

$ sed -nE '/---/{s/.*: (-*)/\1/;N;p}; /FINE/p' file
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39 

/---/パターンが一致する場合:

s/.*: (-*)/\1/=> "FINE: ---" を "---" に置き換える
N;p=> 現在の行を次の行に追加します (たとえば、次の日付スタンプ行を追加)。

/FINE/p => FINEを含む他のすべての行は印刷されます。

もう一つの奇妙な:

$ awk '/---/ { getline h;$0="---\n"h;print } /^FINE/{print }' file

答え2

$ awk 'p=="FINE: ---" && !/FINE/; {p=$0} /FINE/{sub(/FINE: -/, "-"); print}' ip.txt
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
  • {p=$0}現在の行をp変数に保存します。
  • p=="FINE: ---" && !/FINE/前の行がFINE: ---現在の行と一致しないことを確認してくださいFINE。条件が満たされると、現在の行が印刷されます。
  • /FINE/{sub(/FINE: -/, "-"); print}現在行にが含まれている場合、FINEこの関数はsub行からその項目を削除します。その後、行を印刷しますFINE:FINE: ---

以下も使用できます。

awk 'p; {p=0} /FINE/{if($2=="---") {print $2; p=1} else print}'
# or using getline, assuming no errors
awk '/FINE/{if($2=="---") {print $2; getline} print}'

答え3

$ awk '/^FINE:/{print (/---$/ ? $2 ORS p : $0)} {p=$0}' file
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39

答え4

これはfreenodeで提案された内容で、エレガントで読みやすいと思います。

awk '$1 != "FINE:" {h=$0} $2 == "---" {printf "---\n%s\n", h} $1 == "FINE:" && $2 != "---"'

関連情報