获取文件中长度为n的所有可能子串的计数? (不包括空格)

时间:2019-03-11 15:02:51

标签: python macos shell unix awk

我有一些导出文件,您可以假设它们在一行中有很多单词,没有一行是特殊的。我看到这篇文章在文件中生成了不同的单词

https://unix.stackexchange.com/questions/286464/all-possible-permutations-of-words-in-different-files-in-pairs

文件中还有其他一些单词搜索变体。

但是对于长度为4的子字符串,我需要这样的东西。这里有子字符串及其数量。

示例文件内容

no apples 
no apples
mango is great
banana is expensive
test

示例输出为

appl 2
pple 2
ples 2
mang 1
ango 1
grea 1
reat 1
bana 1
anan 1
nana 1
expe 1
xpen 1
pens 1
ensi 1
sive 1
nsiv 1
test 1

子字符串不一定具有任何含义,它们只是文件的子字符串。该文件不大,在最坏的情况下不到5MB,实际上有多个文件,但是我在分析之前将它们合并了。

我想在SO中提出问题,因为如果需要编写一个shell / phyton脚本,但是如果我们可以使用命令轻松地做到这一点,那就更好了。

4 个答案:

答案 0 :(得分:2)

您也可以尝试Perl

perl -lne ' while(/(\S+)/g) { $x=$1; 
      while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }} 
       END { print "$_ $kv{$_}" for(keys %kv) }  ' file

使用您给定的输入

$ cat test.txt
no apples
no apples
mango is great
banana is expensive
test

$ perl -lne ' while(/(\S+)/g) { $x=$1; 
     while($x=~/\b(?=(\w{4}))|\B(?=(\w{4}))\B|(?=(\w{4}))\b/g) { $kv{"$1$2$3"}++ }}
       END { print "$_ $kv{$_}" for(keys %kv) }  ' test.txt
nsiv 1
xpen 1
reat 1
ensi 1
sive 1
ples 2
pple 2
test 1
appl 2
expe 1
anan 1
mang 1
ango 1
bana 1
pens 1
grea 1
nana 1

$

您可以在BEGIN块中将参数设置为

$ perl -lne ' BEGIN { $t=qr(\w{5}) } 
     while(/(\S+)/g) { $x=$1; while($x=~/\b(?=($t))|\B(?=($t))\B|(?=($t))\b/g)
        { $kv{"$1$2$3"}++ }} 
           END { print "$_ $kv{$_}" for(keys %kv) }  ' test.txt
great 1
pples 2
apple 2
expen 1
nsive 1
banan 1
anana 1
ensiv 1
pensi 1
xpens 1
mango 1

$

答案 1 :(得分:1)

您可以使用此awk解决方案来获取所有n个字母子字符串及其频率的列表:

awk -v n=4 '{
for (i=1; i<=NF; i++)
   for (j=1; j<=length($i)-n+1; j++)
      w[substr($i, j, n)]++
}
END {
   for (i in w) print i, w[i]
}' file

appl 2
ensi 1
nana 1
mang 1
sive 1
anan 1
nsiv 1
grea 1
pens 1
xpen 1
bana 1
ples 2
pple 2
expe 1
reat 1
ango 1

答案 2 :(得分:1)

类似下面的内容可以满足您的需求:

while read line 
do 
  for word in $line 
  do 
  [[ ${#word} -eq 3 ]] && echo "$word" $(grep -c "$word" your_file)  
  done 
done < your_file

它将逐行逐字读取您的文件。如果单词长度为3,则会在文件中输出单词及其出现的次数

答案 3 :(得分:1)

所以这里的诱惑是嵌套循环...但是您不想这样做,当然不适合N> 3 ...

在python中有2件事让这变得很简单

  • 过滤器
  • collections.Counter

from collections import Counter

s = open(somefile).read()
# now you have a string with contents of file.
l = s.split()
# now you have a list of words of all lengths
l_filtered = filter(lambda x: len(x)==n, l)
#now you have a filtered list of only words of len n
print (Counter(l_filtered))
#your answer as a dict like Counter object