두 개의 CSV 파일이 있습니다.
이것은 csv1입니다.
11, The Sun Still Shines in Reading, 64312, 464566
13, You and Me Together Again London, 564564, 131355
12, What's the Story Now Your Gone, 4545646, 1124545
17, Hello I love you, 456899, 1259898
이것은 csv2입니다.
69, The Sun Shines, 6464, 52364
12, Tell me your name, 56456, 21345
17, From London to New York, 897944, 234655
97, Reading Still Shines, 545464, 16748967
제목 일치(필드 2에 있음)를 허용하는 이 코드가 있습니다.
cat $csv1 |cut -d, -f2 | while read p; do
grep -i "$p" $csv2
if [ $? -eq 0 ];then
grep -i "$p" $csv1
fi
done
현재 이 코드는 csv1의 각 줄을 살펴보고, csv2에 일치하는 제목이 있는 줄이 있으면 일치하는 줄을 함께 인쇄합니다. 이것은 정말 잘 작동합니다.
그러나 이제는 정확한 제목을 검색하는 대신 일치하는 단어가 3개 이상 있는지 확인하도록 스크립트를 조정하고 싶습니다.
따라서 이 페이지에 있는 csv 데이터의 경우 출력은 다음과 같습니다.
11, The Sun Still Shines in Reading, 64312, 464566
69, The Sun Shines, 6464, 52364
97, Reading Still Shines, 545464, 16748967
이는 상단에 있는 csv1의 줄과 필드 2(제목)에 3개 이상의 일치하는 단어가 있는 csv2의 두 줄로 구성됩니다. 일치하는 단어 수를 어떻게 지정합니까?
편집: 내가 언급하는 것을 잊은 한 가지는 csv1이 csv2보다 줄의 크기가 훨씬 작다는 것입니다(예: 10이 수천에 비해). 생각해 보면 가장 큰 데이터를 정의할 수 있으므로 이것이 실제로 중요하지 않은 것 같습니다. csv1 또는 csv2로 설정합니다.
답변1
보다 쉘 중심적인 솔루션(awk?)이 있을 수 있지만 일반적으로 perl
문제가 이렇게 복잡해지는 경우를 고려합니다. 다음은 모든 항목을 csv2
메모리로 읽어 들여 해당 제목을 값으로 하는 해시의 키로 행을 수집하는 Perl 스크립트입니다 .
그런 다음 을 반복하고 csv1
제목을 가져온 다음 의 각 제목에 대해 csv2
제목의 각 단어가 표시된 횟수를 계산합니다. 보다 크면 desired
일치하는 제목이 의 "source" 줄과 함께 인쇄됩니다 csv1
.
#!/usr/bin/env perl
my @csv2 = ();
open CSV2, "<csv2" or die;
@csv2=<CSV2>;
close CSV2;
my %csv2hash = ();
for (@csv2) {
chomp;
my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title
$csv2hash{$_} = $title;
}
open CSV1, "<csv1" or die;
while (<CSV1>) {
chomp;
my ($title) = $_ =~ /^.+?,\s*([^,]+?),/; #/ match the title
my @titlewords = split /\s+/, $title; #/ get words
my $desired = 3;
my $matched = 0;
foreach my $csv2 (keys %csv2hash) {
my $count = 0;
my $value = $csv2hash{$csv2};
foreach my $word (@titlewords) {
++$count if $value =~ /\b$word\b/i;
last if $count >= $desired;
}
if ($count >= $desired) {
print "$csv2\n";
++$matched;
}
}
print "$_\n" if $matched;
}
close CSV1;