我有兩個 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;