как найти количество слов в текстовом файле? - PullRequest
6 голосов
/ 24 августа 2011

Я могу узнать, сколько раз слово встречается в текстовом файле, как в Linux, которое мы можем использовать

cat filename|grep -c tom

Мой вопрос: как мне найти количество слов, таких как "Том"?и "Джо" в текстовом файле.

Ответы [ 9 ]

3 голосов
/ 24 августа 2011

Поскольку у вас есть пара имен, регулярные выражения - это то, что вам нужно.Сначала я подумал, что это так же просто, как просто рассчитывать grep на регулярное выражение joe или tom, но подумал, что это не учитывает сценарий, когда tom и joe находятся в одной строке (или tom and tom в этом отношении),

test.txt:

tom is really really cool!  joe for the win!
tom is actually lame.


$ grep -c '\<\(tom\|joe\)\>' test.txt
2

Как видно из файла test.txt, 2 - неправильный ответ, поэтому нам нужно было учесть, что имена находятся в одной строке.

Затем я использовал grep -o, чтобы показать только часть совпадающей строки, которая соответствует шаблону, где он дал правильные соответствия шаблону tom или joe в файле.Затем я передал результаты в число строк в wc для количества строк.

$ grep -o '\(joe\|tom\)' test.txt|wc -l
       3

3 ... правильный ответ!Надеюсь, это поможет

3 голосов
/ 24 августа 2011

Хорошо, сначала разбейте файл на слова, затем sort и uniq:

tr -cs '[:alnum:]' '\n' < testdata | sort | uniq -c

Вы используете uniq:

sort filename | uniq -c

1 голос
/ 24 августа 2011

Использовать awk:

{for (i=1;i<=NF;i++)
    count[$i]++
}
END {
    for (i in count)
        print count[i], i
}

Это даст полный подсчет частоты слов для входа.Направьте вывод на grep, чтобы получить нужные поля

awk -f w.awk input | grep -E 'tom|joe'

Кстати, вам не нужно cat в вашем примере, большинство программ, которые действуют как фильтры, могут принимать имя файла в качестве параметра;следовательно, лучше использовать

grep -c tom filename

, если нет, есть большая вероятность того, что люди начнут бросать в вас Бесполезное использование награды Cat ; -)

0 голосов
/ 02 ноября 2012

Чтобы найти все хиты во всех строках

echo "tom is really really cool!  joe for the win!
tom is actually lame." | akw '{i+=gsub(/tom|joe/,"")} END {print i}'
3

Это будет считать "Томтом" как 2 хита.

0 голосов
/ 26 августа 2011
gawk -vRS='[^[:alpha:]]+' '{print}' | grep -c '^(tom|joe|bob|sue)$'

Программа gawk устанавливает разделитель записей на что-либо не алфавитное, поэтому каждое слово будет находиться в отдельной строке. Затем grep подсчитывает строки, которые точно соответствуют одному из слов, которые вы хотите.

Мы используем gawk, потому что POSIX awk не допускает разделитель записей регулярного выражения.

Для краткости, вы можете заменить '{print}' на 1 - в любом случае, это программа Awk, которая просто распечатывает все входные записи («is 1 true? Is is», затем выполните действие по умолчанию, которое {print}. ")

0 голосов
/ 25 августа 2011

Я совсем забыл про grep -f:

cat filename | grep -fc names

Решение AWK:

Предполагая, что имена находятся в файле с именем names:

cat filename | awk 'NR==FNR {h[NR] = $1;ct[i] = 0; cnt=NR} NR !=FNR {for(i=1;i<=cnt;++i) if(match($0,h[i])!=0) ++ct[i] } END {for(i in h) print h[i], ct[i]}' names -

Обратите внимание, что ваш оригинальный grep не ищет слова. например,

$ echo tomorrow | grep -c tom
1

Вам нужно grep -w

0 голосов
/ 24 августа 2011

Вы можете сделать регулярное выражение,

 cat filename |tr ' ' '\n' |grep -c -e "\(joe\|tom\)"
0 голосов
/ 24 августа 2011
  1. Образец, который вы дали, не ищет слова"том". Он будет считать «атом» и «дно» и многое другое.
  2. Grep ищет регулярных выражений . Регулярное выражение, которое соответствует слову "Tom" или "Joe":

    \<\(tom\|joe\)\>
    
0 голосов
/ 24 августа 2011

Вот один из них:

cat txt | tr -s '[:punct:][:space:][:blank:]'| tr '[:punct:][:space:][:blank:]' '\n\n\n' | tr -s '\n' | sort | uniq -c

UPDATE

Решение сценария оболочки:

#!/bin/bash

file_name="$2"
string="$1"

if [ $# -ne 2 ]
  then
   echo "Usage: $0 <pattern to search> <file_name>"
   exit 1
fi

if [ ! -f "$file_name" ]
 then
  echo "file \"$file_name\" does not exist, or is not a regular file"
  exit 2
fi

line_no_list=("")
curr_line_indx=1
line_no_indx=0
total_occurance=0

# line_no_list contains loc k the line number loc k+1 the number
# of times the string occur at that line
while read line
 do
  flag=0
  while [[ "$line" == *$string* ]]
   do
    flag=1
    line_no_list[line_no_indx]=$curr_line_indx
    line_no_list[line_no_indx+1]=$((line_no_list[line_no_indx+1]+1))
    total_occurance=$((total_occurance+1))
# remove the pattern "$string" with a null" and recheck
    line=${line/"$string"/}
  done
# if we have entered the while loop then increment the
# line index to access the next array pos in the next
# iteration
  if (( flag == 1 ))
   then
    line_no_indx=$((line_no_indx+2))
  fi
  curr_line_indx=$((curr_line_indx+1))
done < "$file_name"


echo -e "\nThe string \"$string\" occurs \"$total_occurance\" times"
echo -e "The string \"$string\" occurs in \"$((line_no_indx/2))\" lines"
echo "[Occurence # : Line Number : Nos of Occurance in this line]: "

for ((i=0; i<line_no_indx; i=i+2))
 do
  echo "$((i/2+1)) : ${line_no_list[i]} : ${line_no_list[i+1]} "
done

echo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...