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