计算文件中长度n的所有可能的子字符串?(不包括空间)



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

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

,并且在文件中还有其他一些单词搜索的变体。

但是我需要的是这样的,对于长度四的子字符串。在这里,我们有substring及其数量。

示例文件内容

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,实际上有多个文件,但我在分析之前将它们合并。

我想在这样做,因为如果这需要写一个shell/phyton脚本,但是如果我们可以轻松地使用命令做到这一点,那将是更赞赏的。

您也可以尝试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
$

您可以在开始块内部参数化

$ 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
$

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

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

以下类似的事情可能会做您需要的事情:

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

它将按行读取您的文件,word。如果单词长度为3,它将输出单词及其在文件中的事件数量

,所以这里的诱惑是筑巢循环...但是您不想这样做,当然不是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

最新更新