Linux 如何使用bash脚本计算单词中最常见的3个字母序列

Linux 如何使用bash脚本计算单词中最常见的3个字母序列,linux,bash,awk,sed,Linux,Bash,Awk,Sed,我有一个像这样的示例文件 XYZAcc ABCAccounting Accounting firm Accounting Aco Accounting Acompany Acoustical consultant 在这里,我需要grep一个单词中最常见的3个字母序列 输出应该是 acc=5 aco=3 这在Bash中可能吗 我完全不知道如何用awk、sed和grep来完成它 任何可能的线索 PS:没有输出,因为我不知道怎么做,我不想写不必要的awk-F,xyz abc。。。这对任何地方都没有帮

我有一个像这样的示例文件

XYZAcc
ABCAccounting
Accounting firm
Accounting Aco
Accounting Acompany
Acoustical consultant
在这里,我需要grep一个单词中最常见的3个字母序列

输出应该是

acc=5 aco=3

这在Bash中可能吗

我完全不知道如何用awk、sed和grep来完成它

任何可能的线索


PS:没有输出,因为我不知道怎么做,我不想写不必要的awk-F,xyz abc。。。这对任何地方都没有帮助

以下是如何开始我认为您正在尝试做的事情:

$ cat tst.awk
BEGIN { stringLgth = 3 }
{
    for (fldNr=1; fldNr<=NF; fldNr++) {
        field = $fldNr
        fieldLgth = length(field)
        if ( fieldLgth >= stringLgth ) {
            maxBegPos = fieldLgth - (stringLgth - 1)
            for (begPos=1; begPos<=maxBegPos; begPos++) {
                string = tolower(substr(field,begPos,stringLgth))
                cnt[string]++
            }
        }
    }
}
END {
    for (string in cnt) {
        print string, cnt[string]
    }
}
这可能适合您(GNU-sed、sort和uniq):

使用第一个sed调用输出3个字母的小写单词

把单词分类

数一数复制品

按与数字相反的顺序对计数进行排序,并保持字母顺序

使用第二个sed调用将结果处理为所需的格式


如果您只需要具有重复项且按字母顺序和大小写排列的行,请使用:

sed -E 's/.(..)/&\n\1/;/^\S{3}/P;D' file |
sort |
uniq -cd |
sed -En 's/^\s*(\S+)\s*(\S+)/\2 = \1/;H;$!b;x;s/\n/ /g;s/.//p

这是该方法的替代方法。它的循环更少,但需要更多的内存。这个想法是不关心空格或任何非字母字符。最后我们把它们过滤掉

awk -v n=3 '{ for(i=length-n+1;i>0;--i) a[tolower(substr($0,i,n))]++ }
            END {for(s in a) if (s !~ /[^a-z]/) print s,a[s] }' file
当您使用GNUAWK时,您可以通过将每个记录设置为一个单词来进行一些不同的优化。这样就不需要进行末端选择:

awk -v n=3 -v RS='[[:space:]]' '
    (length>=n){ for(i=length-n+1;i>0;--i) a[tolower(substr($0,i,n))]++ }
    END {for(s in a) print s,a[s] }' file

由于部分匹配,解决方案会很复杂-这不是单词匹配,您发布的输入文件在我看来不像CSV。你是否只发布了一列你真正的CSV?请发布真正具有代表性的示例输入和预期输出,涵盖您的所有用例(跨行匹配、字段内匹配、部分匹配与完整匹配、regexp与字符串匹配等)。在您的示例中,
cou
也会出现5次。Bash/grep/sed并不是这种操作的最佳语言。第一个问题,“存在什么独特的三字母代码”很难回答。@EdMorton这是一个我保存为CSV的文件。。仅1列;))然后它只是一个纯文本文件,不管你在它的末尾加了什么扩展名。您可以将其命名为foo.html或foo.docx或任何其他名称,但这并不意味着它是那种类型的文件-内容决定了它是什么类型的文件,在本例中,它只是一个纯文本文件,因为其中没有分隔符,这将使它成为CSV。说这是一个CSV文件是令人困惑的。哈,我越来越接近了,我做了
1-NF
,但后来
tolower
和循环
j=1;J
awk -v n=3 '{ for(i=length-n+1;i>0;--i) a[tolower(substr($0,i,n))]++ }
            END {for(s in a) if (s !~ /[^a-z]/) print s,a[s] }' file
awk -v n=3 -v RS='[[:space:]]' '
    (length>=n){ for(i=length-n+1;i>0;--i) a[tolower(substr($0,i,n))]++ }
    END {for(s in a) print s,a[s] }' file