如何在文本文件中找到多个单词的计数?

时间:2011-08-24 07:28:07

标签: linux shell

我能够找到一个单词出现在文本文件中的次数,就像我们可以使用的Linux一样

cat filename|grep -c tom

我的问题是如何在文本文件中找到多个单词的数量,如“tom”和“joe”。

9 个答案:

答案 0 :(得分:3)

好的,首先将文件拆分为单词,然后sortuniq

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

您使用uniq

sort filename | uniq -c

<击>

答案 1 :(得分:3)

由于你有几个名字,正则表达式就是这种方式。起初我认为它只是对joe或tom的正则表达式上的grep计数一样简单,但是这并没有说明tom和joe在同一行上的情况(或tom和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 ...正确答案!希望这有帮助

答案 2 :(得分:1)

使用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

如果没有,人们很可能会开始向你投掷Useless Use of Cat Award; - )

答案 3 :(得分:0)

这是一个:

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

<强>更新

shell脚本解决方案:

#!/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

答案 4 :(得分:0)

  1. 您提供的示例搜索“tom”。它会计算“原子”和“底部”等等。
  2. Grep搜索正则表达式。匹配单词“tom”或“joe”的正则表达式是

    \<\(tom\|joe\)\>
    

答案 5 :(得分:0)

你可以做正则表达式,

 cat filename |tr ' ' '\n' |grep -c -e "\(joe\|tom\)"

答案 6 :(得分:0)

我完全忘记了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不会搜索单词。 e.g。

$ echo tomorrow | grep -c tom
1

您需要grep -w

答案 7 :(得分:0)

gawk -vRS='[^[:alpha:]]+' '{print}' | grep -c '^(tom|joe|bob|sue)$'

gawk程序将记录分隔符设置为非字母的任何内容,因此每个单词都将以单独的行结束。然后grep计算与您想要的单词之一匹配的行。

我们使用gawk,因为POSIX awk不允许使用正则表达式记录分隔符。

为简洁起见,您可以将'{print}'替换为1 - 无论哪种方式,它都是一个只打印出所有输入记录的Awk程序(“1是真的吗?它是吗?那么做默认操作,即{print}。“)

答案 8 :(得分:0)

查找所有行中的所有匹配

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

这会将“tomtom”视为2次点击。