如何计算文件中特定行中特定字符串的出现次数?

如何计算文件中特定行中特定字符串的出现次数?

我知道我可以使用 wc 返回文件中的总字数(和行数):

wc <filename>

有没有办法返回文件特定行上特定字符串的计数,如下所示:

wc <filename> -<flag> <line number> -<flag> <string> 

答案1

这需要分三步完成:

  1. 选择行号 N (示例使用第 42 行):

    sed '42!d'
    
  2. 在该行中搜索特定模式(这里是字符串/正则表达式hello)的所有出现,并分别打印它们:

    grep -o 'hello'
    
  3. 计算匹配次数:

    wc -l
    

或者将其放在一个命令管道中,读取自file.txt

sed '42!d' file.txt | grep -o 'hello' | wc -l

答案2

这是将 Unix 工具整合到管道中的一个很好的用例。

line=5
str="ipsum"
sed -n "${line}p" filename | grep -o -- "$str" | wc -l

sedp命令输出文件中的给定行,并将其输入到 grep 中。Grep 的-o选项告诉它输出给定字符串的所有匹配项,每个匹配项都输出在单独的行上。Grep 的输出被输入到 wc,后者计算行数。

答案3

Python

这是其中一种方法Python通过列表推导(请参阅下面的替代较短版本)。

$ python -c 'import sys;print([ l for i,l in enumerate(sys.stdin,1) if i==2][0].count("word"))' < input.txt                                          
3
$ cat input.txt
nothing here
word and another word, and one more word
last line

工作原理:

  • 我们用-c标志运行python解释器,命令包含在单引号内;
  • 输入文件通过 shell 操作符input.txt重定向到stdinpython 解释器的流中<。因此我们需要sys模块。
  • 使用列表理解结构[something for item in something],我们从中读取文本行sys.stdin
  • enumerate(sys.stdin,1)允许我们计数枚举行,即,随着列表推导的每次迭代,我们将把文本行放入l变量中,并将索引放入i变量中,从 1 开始计数。
  • i==2仅过滤出索引等于 2 的行。这样我们就知道要提取哪一行。
  • 因此,我们的列表将只包含一个项目,并且其在列表中的索引是0。因此,我们将该项目称为[<list comprehension stuff here>][0]。 -.count("word")实际上是执行计数工作的。根据定义,它返回字符串中子字符串不重叠出现的次数。
  • 最后,所有这些东西都包含在print()语句中。因此,无论该.count()方法返回什么数字,都会显示在屏幕上。

简短版本

在 Python 中执行相同操作的更短方法是使用readlines()方法而不是列表推导,并引用readlines()生成的列表中的特定项。请注意,这readlines()会生成一个列表,而 Python 中的列表是从 0 开始索引的,这意味着如果您想读取行 x,则应该引用列表项 x-1。例如,

$ python -c 'import sys;print(sys.stdin.readlines()[1].count("word"))' < input.txt       
3

sed + grep

当然,我们不必只使用脚本语言。sed我们grep提供足够的工具来满足我们的需求。我们grep -c可以计算匹配行的出现次数,所以我们所要做的就是提取我们需要的特定行,并将该行中的所有单词拆分成单独的行。如下所示:

$ sed -n  '2{s/ /\n/g;p}' input.txt | grep -c 'word'
3

答案4

其中一种方法是perl

perl -lne '
  BEGIN{($lineno, $str) = splice @ARGV,0,2} 
  print $c = () = /$str/g if $. == $lineno
' <lineno> <string> <filename>

相关内容