별도의 csv 파일에 있는 필드에서 3개 이상의 단어 일치

별도의 csv 파일에 있는 필드에서 3개 이상의 단어 일치

두 개의 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;

관련 정보