部分的に重複した連続行を削除しますが、最初の行と最後の行は保持します。

部分的に重複した連続行を削除しますが、最初の行と最後の行は保持します。

1行に6つの値を持つタイムスタンプを持つログファイルがあり、同じ値を持つ連続行を削除し(タイムスタンプを無視して)、各反復セットの最初の行と最後の行を保持してデータ量を減らしたいと思います。 bashスクリプトを使用する方が良いです。魔法sedawk命令の組み合わせでなければなりません。

ファイルを複数回解析する必要がある場合でも、一度に3行ずつ読み、中間行を削除するのが良い解決策です。

ソースファイル:

1447790360      99999   99999   20.25   20.25   20.25   20.50
1447790362      20.25   20.25   20.25   20.25   20.25   20.50
1447790365      20.25   20.25   20.25   20.25   20.25   20.50
1447790368      20.25   20.25   20.25   20.25   20.25   20.50
1447790371      20.25   20.25   20.25   20.25   20.25   20.50
1447790374      20.25   20.25   20.25   20.25   20.25   20.50
1447790377      20.25   20.25   20.25   20.25   20.25   20.50
1447790380      20.25   20.25   20.25   20.25   20.25   20.50
1447790383      20.25   20.25   20.25   20.25   20.25   20.50
1447790386      20.25   20.25   20.25   20.25   20.25   20.50
1447790388      20.25   20.25   99999   99999   99999   99999
1447790389      99999   99999   20.25   20.25   20.25   20.50
1447790391      20.00   20.25   20.25   20.25   20.25   20.50
1447790394      20.25   20.25   20.25   20.25   20.25   20.50
1447790397      20.25   20.25   20.25   20.25   20.25   20.50
1447790400      20.25   20.25   20.25   20.25   20.25   20.50

望ましい結果:

1447790360      99999   99999   20.25   20.25   20.25   20.50
1447790362      20.25   20.25   20.25   20.25   20.25   20.50
1447790386      20.25   20.25   20.25   20.25   20.25   20.50
1447790388      20.25   20.25   99999   99999   99999   99999
1447790389      99999   99999   20.25   20.25   20.25   20.50
1447790391      20.00   20.25   20.25   20.25   20.25   20.50
1447790394      20.25   20.25   20.25   20.25   20.25   20.50
1447790400      20.25   20.25   20.25   20.25   20.25   20.50

答え1

uniqは(一種の)完璧なツールです。デフォルトでは、uniqではコレクションの最初の行を保持/表示できますが、最後の行は維持/表示できません。

uniqには、最初のいくつかのフィールドをスキップできる-fフラグがあります。

トップユニークから:

   -f, --skip-fields=N
          avoid comparing the first N fields

   -s, --skip-chars=N
          avoid comparing the first N characters

   A field is a run of blanks (usually spaces and/or TABs), then non-blank characters.  Fields are skipped before chars.

uniq -c を使用してカウントを表示し、uniq が実行する操作を確認する例:

-bash-4.2$ uniq -c -f 1 original_file
  1 1447790360      99999   99999   20.25   20.25   20.25   20.50
  9 1447790362      20.25   20.25   20.25   20.25   20.25   20.50
  1 1447790388      20.25   20.25   99999   99999   99999   99999
  1 1447790389      99999   99999   20.25   20.25   20.25   20.50
  1 1447790391      20.00   20.25   20.25   20.25   20.25   20.50
  3 1447790394      20.25   20.25   20.25   20.25   20.25   20.50

良い。欲しいものにとても近いです。そしてそれは簡単です。しかし、グループの最後の一致行がありません。 。 。 。

この問題については、uniqのグループ化オプションも興味深いです。 。 。

   --group[=METHOD]
          show all items, separating groups with an empty line METHOD={separate(default),prepend,append,both}

   -D, --all-repeated[=METHOD]
          print all duplicate lines groups can be delimited with an empty line METHOD={none(default),prepend,separate}

たとえば、グループごとの uniq です。 。 。

    -bash-4.2$ uniq --group=both -f 1 original_file 

1447790360      99999   99999   20.25   20.25   20.25   20.50

1447790362      20.25   20.25   20.25   20.25   20.25   20.50
1447790365      20.25   20.25   20.25   20.25   20.25   20.50
1447790368      20.25   20.25   20.25   20.25   20.25   20.50
1447790371      20.25   20.25   20.25   20.25   20.25   20.50
1447790374      20.25   20.25   20.25   20.25   20.25   20.50
1447790377      20.25   20.25   20.25   20.25   20.25   20.50
1447790380      20.25   20.25   20.25   20.25   20.25   20.50
1447790383      20.25   20.25   20.25   20.25   20.25   20.50
1447790386      20.25   20.25   20.25   20.25   20.25   20.50

1447790388      20.25   20.25   99999   99999   99999   99999

1447790389      99999   99999   20.25   20.25   20.25   20.50

1447790391      20.00   20.25   20.25   20.25   20.25   20.50

1447790394      20.25   20.25   20.25   20.25   20.25   20.50
1447790397      20.25   20.25   20.25   20.25   20.25   20.50
1447790400      20.25   20.25   20.25   20.25   20.25   20.50

その後、grepを介して各空行の前後の行を見つけて、空行を削除します。

-bash-4.2$ uniq --group=both -f 1 original_file |grep -B1 -A1 ^$ |grep -Ev "^$|^--$"
1447790360      99999   99999   20.25   20.25   20.25   20.50
1447790362      20.25   20.25   20.25   20.25   20.25   20.50
1447790386      20.25   20.25   20.25   20.25   20.25   20.50
1447790388      20.25   20.25   99999   99999   99999   99999
1447790389      99999   99999   20.25   20.25   20.25   20.50
1447790391      20.00   20.25   20.25   20.25   20.25   20.50
1447790394      20.25   20.25   20.25   20.25   20.25   20.50
1447790400      20.25   20.25   20.25   20.25   20.25   20.50

ダダダ!良い。

答え2

awkライナーに付属:

awk '{n=$2$3$4$5$6$7}l1!=n{if(p)print l0; print; p=0}l1==n{p=1}{l0=$0; l1=n}END{print}' file

ポイントは、複数の変数を操作することです。n最初のフィールドを除くすべてのフィールドを現在の行に保存すると、前の行と前のすべての行がl1同じになります。l0これはp、前の行が印刷されたかどうかを示すフラグです。

答え3

Perlが構造に来ます:

perl -ne '($t, $r) = /([0-9]+\s+)(.*)/;
          print "$pt$p\n$_" if $r ne $p;
          $p = $r;
          $pt = $t;
          }{
          print $t, $r' input-file \
| sort -nu | tail -n+2
  • -n入力を1行ずつ読みます。
  • $t$r「残り」はタイムスタンプにスペースを加えたものです。
  • $p以前のブレーキで、$pt以前のタイムスタンプです。
  • 最後の行は常に印刷されます。

Perlはいくつかの行を2回印刷するため、sort -nu重複した内容は削除する必要があります。tail最初の空行を削除します。

答え4

sed -e:t -e'$!{1N;N;s/\( .*\)\(\n[^ ]*\1\)\{2\}$/\1\2/;tt' -e'P;D;}' <in >out

...それはうまくいきます。これは、2番目のスペースで区切られたフィールドから始まり、同じと見なされる一連の3つの入力ラインから2番目の入力ラインを再帰的に置き換えます。そうすることができなくなるまで、置き換える各入力ラインを置き換えるために、他の入力ラインを引き続き描画します。同様の3行が一致しない場合にのみ、Pバッファの最初の行を印刷してから削除し、残りのD2行と次の入力行に再試行するためにループバックします。

GNUまたはBSDの使用sed

sed -Ee:t -e'1N;$!N;s/( .*)(\n[^ ]*\1){2}$/\1\2/;tt' -eP\;D <in >out

1447790360      99999   99999   20.25   20.25   20.25   20.50
1447790362      20.25   20.25   20.25   20.25   20.25   20.50
1447790386      20.25   20.25   20.25   20.25   20.25   20.50
1447790388      20.25   20.25   99999   99999   99999   99999
1447790389      99999   99999   20.25   20.25   20.25   20.50
1447790391      20.00   20.25   20.25   20.25   20.25   20.50
1447790394      20.25   20.25   20.25   20.25   20.25   20.50
1447790400      20.25   20.25   20.25   20.25   20.25   20.50

関連情報