동일한 형식의 파일이 2개 있고 열 1개를 제외하고 데이터는 동일합니다.
파일 1의 예시 라인:
"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295
파일 2의 예시 라인:
"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321
물론 이 파일에는 다른 줄도 있지만 제가 관심을 두는 부분은 다음과 같습니다.
파일 2에서 동일한 엔터티와 관련된 모든 줄, 즉 $3
파일 1에 있는 줄 중 최신 타임스탬프를 가진 줄을 제거하고 해당 줄을 유지하고 싶습니다. 쉬어 알았어.
예제 행에서는 열 1의 날짜 문자열에서 볼 수 있듯이 파일 1의 행이 더 최신임을 알 수 있습니다. 이제 행의 마지막 정수는 열 1의 실제 epoch이므로 해당 열을 사용하여 날짜를 비교하고 정렬할 수 있습니다.
다음과 같이 Perl로 스크립트를 작성하면 됩니다.
#!/usr/bin/perl
use strict;
use warnings;
my $file_a = "file1";
my $file_b = "file2";
open my $file_a_h, $file_a or die "Could not open $file_a";
sub timestamp_users {
my ($fh) = @_;
my %recs;
while ( my $line =<$fh> ) {
my @items = split ",", $line;
my $user = $items[3];
$recs{$user} = $items[5];
}
return \%recs;
}
my $file_a_recs = timestamp_users($file_a_h);
close $file_a_h;
open my $file_b_h, $file_b or die "Could not open $file_b";
my $file_b_recs = timestamp_users($file_b_h);
close $file_b_h;
my $count = 0;
while (my ($user, $last_time) = each %$file_b_recs) {
if(exists $file_a_recs->{$user} && $last_time >= $file_a_recs->{$user}) {
++$count;
`echo $user >> result.txt`;
}
}
print "count: $count\n";
이 경우에는 사용자를 출력한 다음 grep -v
file_b에서 필요한 행을 찾으려면 작업을 수행해야 합니다.
하지만 명령줄 도구를 사용하여 이를 수행할 수 있는 방법이 있습니까?
이 접근 방식은 나에게 너무 복잡해 보입니다.
고쳐 쓰다:
파일 1의 예시 라인:
"1/30/2017 11:14:55 AM",Valid customer,jim.smith,NY,1485771295
"1/26/2017 5:06:11 AM",New customer,john.doe,CA,1485403571
"1/30/2017 4:14:30 AM",New customer,tim.jones,CO,1485746070
파일 2의 예시 라인:
"1/26/2017 8:02:01 PM",Valid customer,jim.smith,NY,1485457321
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233
예상 출력:
"1/30/2017 11:14:03 AM",New customer,john.doe,CA,1485771243
"1/30/2017 11:09:36 AM",New customer,tim.jones,CO,1485770976
"1/30/2017 11:13:53 AM",New customer,bill.smith,CA,1485771233
답변1
두 파일의 각 줄의 최신 버전을 얻으려면 다음을 수행하십시오.
$ cat file1 file2 | sort -t',' -k3,3 -k5,5nr | sort -t',' -u -k3,3 -o newest
그러면 파일이 연결되고 필드 3과 5의 필드를 정렬 키로 사용하여 레코드가 정렬됩니다. 이렇게 하면 각 사람의 최신 기록이 먼저 나오도록 연결된 파일이 정렬됩니다(마지막 열의 타임스탬프 덕분에). 마지막 정렬에서는 필드 3을 정렬 키로 사용하고 해당 필드를 기반으로 고유하게 정렬합니다. 이렇게 하면 파일에 있는 모든 사람의 최신 기록만 남게 됩니다 newest
.
그런 다음 에서 행의 보완을 만듭니다 newest
. 즉, 각 사람의 최신 기록보다 오래된 두 파일의 모든 기록을 만듭니다.
$ cat file1 file2 | grep -v -F -x -f newest >older
전체 행( )에서 고정 문자열 일치( )를 수행 grep
하고 ( )에서 일치하지 않는 모든 행을 반환합니다. 이러한 행은 에 저장됩니다.-F
-x
-v
newest
older
마지막 단계는 파일 file2
에 있는 모든 줄을 삭제하는 것입니다 older
.
$ grep -v -F -x -f older file2 >new-file2