Получить подсчет всех возможных подстрок длины n в файле? (исключая пробелы) - PullRequest
1 голос
/ 11 марта 2019

У меня есть несколько файлов экспорта, вы можете предположить, что они содержат много слов в одной строке, и ни одна строка не является особенной.Я видел этот пост, чтобы генерировать разные слова в файле

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

, а также есть некоторые другие варианты поиска слов в файле.

Но что мне нужноэто что-то вроде этого для подстрок длины четыре.Здесь у нас есть подстрока и ее количество.

Пример файла содержимого

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

Подстроки не обязательно имеют какое-либо значение,они просто подстроки файла.Файл не большой, менее 5 МБ в худшем случае, на самом деле есть несколько файлов, но я объединил их перед анализом.

Я хотел спросить в SO, потому что в случае, если это требует написания сценария оболочки / фитона, но если мы сможем сделать это легко с помощью команд, это будет более ценно.

Ответы [ 4 ]

2 голосов
/ 11 марта 2019

Вы также можете попробовать 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 голос
/ 11 марта 2019

что-то вроде ниже может сделать то, что вам нужно:

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

Он будет читать ваш файл построчно, слово за словом. Если длина слова равна 3, он выведет слово и количество его вхождений в файл

1 голос
/ 11 марта 2019

так что соблазн здесь заключается в том, чтобы вкладывать циклы ... но вы не хотите этого делать, конечно, не для 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
1 голос
/ 11 марта 2019

Вы можете использовать это решение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...