частота слов из файла с использованием частичного совпадения - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть такой текстовый файл:

tom
and
jerry
went
to
america
and
england

Я хочу получить частоту каждого слова.

Когда я попробовал следующую команду

sort test.txt|uniq -c

Я получил следующий вывод

   1 america
   2 and
   1 england
   1 jerry
   1 to
   1 tom
   1 went

Но мне тоже нужны частичные совпадения.то есть слово to присутствует в слове tom.Таким образом, мое ожидаемое количество слов to равно 2. Возможно ли использовать unix команды?

Ответы [ 4 ]

4 голосов
/ 20 сентября 2019
$ cat tst.awk
NR==FNR {
    cnt[$1] = 0
    next
}
{
    for (word in cnt) {
        cnt[word] += gsub(word,"&")
    }
}
END {
    for (word in cnt) {
        print word, cnt[word]
    }
}

$ awk -f tst.awk file file
went 1
america 1
to 2
and 3
england 1
jerry 1
tom 1

Поскольку вы упомянули в комментарии о нехватке ОЗУ, если у вас недостаточно ОЗУ для одновременного хранения всех уникальных слов из вашего файла в памяти, выполните описанное выше в цикле N (10?100? 1000?) Тысяч слов за раз, например (псевдокод, похожий на bash):

sort -u file > tmp
for (( i=1; i<=$(wc -l < tmp); i+=10000 )); do
    awk -f tst.awk <(head -n "$i" tmp | tail -n 10000) file
done
1 голос
/ 20 сентября 2019

Perl был создан для подобных вещей, если он у вас есть:

$ perl -e '@lines=<>;for $x(@lines){chomp $x;print 0+grep(/$x/,@lines), " $x\n"}' text_file
1 tom
3 and
1 jerry
1 went
2 to
1 america
3 and
1 england

<> в контексте списка считывает все строки сразу в массив.

chomp избавляется от завершающего символа новой строки.

* 0+ помещает grep в скалярный контекст, где вычисляется только счетчик.

1 голос
/ 20 сентября 2019

Сценарий:

#!/bin/bash

while IFS= read -r word; do
    count=`grep -o "${word}" file | wc -l`
    echo "${word} : ${count}"
done < file

Вывод:

Том: 1 и: 3 Джерри: 1 Прошел: 1 до: 2 Америка: 1 и: 3 Англия: 1

1 голос
/ 20 сентября 2019

Вы можете вызывать grep для каждого уникального слова вашего файла:

while IFS= read -r pattern; do
    count="$(grep -o "$pattern" test.txt | wc -l)" # can't use grep -c as it counts lines
    printf '%s: %d\n' "$pattern" "$count"
done < <(sort test.txt | uniq)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...