符合單獨 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 中的行,後面跟著 csv2 中的兩行,它們在字段 2(標題)中具有 3 個或更多匹配單字。如何指定匹配單字的數量?

編輯:我忘記提到的一件事是,csv1 的行數比csv2 的大小要小得多(就像10 與數千相比),儘管考慮一下,我想這並不重要,因為我可以定義最大的數據設定為 csv1 或 csv2。

答案1

perl可能有一個更以 shell 為中心的解決方案(awk?),但當問題變得如此複雜時我通常會轉向。這是一個 perl 腳本,它將所有內容讀csv2入內存,將行作為鍵收集到散列中,其值是相應的標題。

然後循環遍歷csv1,取出標題,然後對於 中的每個標題csv2,計算標題中每個單字出現的次數。如果大於desired,則列印符合的標題及其來自 的「來源」行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;

相關內容