同じ値を持つ行を選択[閉じる]

同じ値を持つ行を選択[閉じる]

同じ値を持つ行の選択に問題があります。私のデータが大きすぎて、これを行ごとに実行できません。これを実行できるスクリプトを教えてください。

私のデータは次のとおりです。

ファイル名:temp

Start day   hour    end day        hour Value
01/04/2000  22:00   01/05/2000  09:00   -9
01/05/2000  09:00   01/06/2000  09:00   -9
01/06/2000  09:00   01/07/2000  09:00   -9
01/07/2000  09:00   01/08/2000  09:00   -9
01/08/2000  09:00   01/09/2000  09:00   -9
01/09/2000  09:00   01/10/2000  09:00   -9
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/12/2000  09:00   01/13/2000  09:00   -9
01/15/2000  09:00   01/16/2000  09:00   -9
01/16/2000  09:00   01/17/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/19/2000  09:00   01/20/2000  09:00   -9
01/20/2000  09:00   01/21/2000  09:00   -9
01/21/2000  09:00   01/22/2000  09:00   -9
01/22/2000  09:00   01/23/2000  09:00   -9
01/23/2000  09:00   01/24/2000  09:00   -9
01/24/2000  09:00   01/25/2000  09:00   -9
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9

たとえば、上記の2000年1月18日は、「開始日」として2回、「終了日」として2回表示されます。だから、01/18/2000「開始日」または「終了日」の行を含めたいと思います。

上記データの出力は以下の通りです。

Start day   hour    end day        hour Value
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9

答え1

私が正しく理解したら、開始日または終了日が繰り返される行が欲しいでしょう。これにより、次のようになります。

awk 'NR==FNR{s[$1]++;e[$3]++;next}
     FNR == 1 || s[$1]>1 || e[$3]>1' temp temp

これはファイルに2つのパスを作成することです。最初のパスでは開始日と終了日の発生回数を計算し、2番目のパスでは開始日または終了日の発生回数が1より大きい行を出力します。

答え2

開始日と終了日が同じ行である場合(前の行を参照しない場合):

perl -ne 'print if(m!^(\d{2}/\d{2}/\d{4})\s+\d{2}:\d{2}\s+\1!);' < file

^行の始まり

(\d{2}/\d{2}/\d{4})日付と店舗が一致します(参照できるように)\1

\s+\d{2}:\d{2}\s+1 つ以上のスペース 2 桁のコロン 2 桁 次の 1 つ以上のスペース

\1「逆参照」保存日

一致すればprintラインです。

答え3

私はあなたのニーズを満たすことを望むPerlスクリプトを書いています。例で提供されたデータがというファイルにあるとしますtemp

#!/usr/bin/perl

### ./timetract.pl

## 01/10/2000  09:00   01/11/2000  09:00   -9
## 01/11/2000  09:00   01/11/2000  21:30   -9
## 01/11/2000  22:30   01/12/2000  09:00   -9
## ...
## 01/17/2000  09:00   01/18/2000  09:00   -9
## 01/18/2000  09:00   01/18/2000  22:45   -9
## 01/18/2000  22:50   01/19/2000  09:00   0.15
#  ...
## 01/25/2000  09:00   01/26/2000  00:35   -9
## 01/26/2000  00:35   01/26/2000  09:00   -9
## 01/26/2000  09:00   01/27/2000  09:00   -9
## 01/27/2000  09:00   01/28/2000  09:00   -9

use strict;
use warnings;
use feature qw( say );

open (my $fh, "<", "temp") || die "Can't open temp: $!";

my ($prevEndDate, @middleRow, $s1, $s2, $mRow) = "";

for my $cRow (<$fh>) {
  chomp($cRow);

  my @currentRow = split(/\s+/, $cRow);
  next if $currentRow[0] =~ /Start/;  # skip first row

  ## col1        col2    col3        col4    col5
  ## ----        ----    ----        ----    ----
  ## 01/27/2000  09:00   01/28/2000  09:00   -9

  # identify that we're on the last row of a block that
  # we're interested in, print it, reset & go to the next row
  if ($currentRow[0] eq $prevEndDate && $s2) {
    say $cRow;
    $s1 = $s2 = 0; # reset states, get ready for next block
    next;
  }

  # identify that we're in the middle of a block that
  # we're interested in, so save current row as a middle row
  if ($currentRow[0] ne $currentRow[2]) {
    $prevEndDate = $currentRow[2];  
    @middleRow   = @currentRow;
    $mRow        = $cRow;
    next;
  }

  # identified beginning row of a block of rows that we're interested in
  $s1 = 1 if ($prevEndDate eq $currentRow[0]);
  # identified middle row of a block of rows that we're interested in
  $s2 = 1 if ($s1 == 1 && $currentRow[0] eq $currentRow[2]);

  say $mRow;
  say $cRow;
}

close ($fh);

# vim: set ts=2 nolist :

実行すると、次の出力が表示されます。

$ ./timeextract.pl 
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9

関連情報