동일한 값을 가진 행을 선택하는 데 문제가 있습니다. 내 데이터가 너무 커서 이 작업을 행별로 수행할 수 없습니다. 이를 수행할 수 있는 스크립트를 알려주시기 바랍니다.
내 데이터는 다음과 같습니다.
파일 이름: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