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