동일한 값을 가진 행 선택 [닫기]

동일한 값을 가진 행 선택 [닫기]

동일한 값을 가진 행을 선택하는 데 문제가 있습니다. 내 데이터가 너무 커서 이 작업을 행별로 수행할 수 없습니다. 이를 수행할 수 있는 스크립트를 알려주시기 바랍니다.

내 데이터는 다음과 같습니다.

파일 이름: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일은 "시작일"로 두 번, "종료일"로 두 번 나타납니다. 그래서 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

이는 파일에 두 개의 패스를 만드는 것입니다. 첫 번째 패스에서는 시작 날짜와 종료 날짜의 발생 횟수를 계산하고, 두 번째 패스에서는 시작 날짜 또는 종료 날짜의 발생 횟수가 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

관련 정보