4

我有两个清单。我需要确定第一个列表中的哪个单词最常出现在第二个列表中。第一个list1.txt包含单词列表,按字母顺序排序,没有重复。我使用了一些脚本来确保每个单词出现在唯一的行上,例如:

canyon
fish
forest
mountain
river

第二个文件list2.txt是 UTF-8 格式,还包含许多项目。我还使用了一些脚本来确保每个单词出现在唯一的行上,但有些项目不是单词,有些可能会出现多次,例如:

fish
canyon
ocean
ocean
ocean
ocean
1423
fish
109
fish
109
109
ocean
  • 该脚本应输出最常匹配的项目。例如,如果使用上面的 2 个文件运行,输出将是“fish”,因为该词list1.txt最常出现在list2.txt.

这是我到目前为止所拥有的。首先,它搜索每个单词并创建一个包含匹配项的 CSV 文件:

#!/bin/bash
while read -r line
do
    count=$(grep -c ^$line list2.txt)
    echo $line”,”$count >> found.csv
done < ./list1.txt

之后,found.csv按第二列降序排序。输出是出现在第一行的单词。不过我不认为这是一个好的脚本,因为它效率不高,并且可能没有最常见的匹配项,例如:

  • 如果 2 个或多个单词之间存在平局,例如“fish”、“canyon”和“forest”,每个单词出现 5 次,而没有其他单词出现频率相同,则输出将是按字母顺序排列的这 3 个单词,以逗号分隔,例如:“峡谷、鱼、森林”。
  • 如果 from 中没有list1.txt出现任何单词list2.txt,则输出只是文件中的第一个单词list1.txt,例如“canyon”。

如何创建一个更有效的脚本来查找第一个列表中的哪个单词最常出现在第二个列表中?

4

3 回答 3

7

您可以使用以下管道:

grep -Ff list1.txt list2.txt | sort | uniq -c | sort -n | tail -n1

F告诉 grep 搜索文字单词,f告诉它list1.txt用作要搜索的单词列表。其余的对匹配项进行排序,计算重复项,并根据出现次数对它们进行排序。最后一部分选择最后一行,即最常见的一行(加上出现次数)。

于 2012-09-12T09:06:03.930 回答
2
> awk 'FNR==NR{a[$1]=0;next}($1 in a){a[$1]++}END{for(i in a)print a[i],i}' file1 file2 | sort -rn|head -1
于 2012-09-12T09:19:32.810 回答
1

假设 'list1.txt' 已排序,我将使用 unix join

sort list2.txt | join -1 1 -2 1 list1.txt - | sort |\
   uniq -c | sort -n | tail -n1
于 2012-09-12T09:16:49.390 回答