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

Don*_*n P 7 command-line wc

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

wc <filename>
Run Code Online (Sandbox Code Playgroud)

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

wc <filename> -<flag> <line number> -<flag> <string> 
Run Code Online (Sandbox Code Playgroud)

Byt*_*der 10

这需要分三步完成:

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

    sed '42!d'
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在该行中搜索所有出现的特定模式(此处为字符串/正则表达式hello)并分别打印:

    grep -o 'hello'
    
    Run Code Online (Sandbox Code Playgroud)
  3. 计算比赛:

    wc -l
    
    Run Code Online (Sandbox Code Playgroud)

或者把它放在一个命令管道中,读取file.txt

sed '42!d' file.txt | grep -o 'hello' | wc -l
Run Code Online (Sandbox Code Playgroud)

  • @hildred grep 的`-c` 计算匹配*行* - 获取单行中匹配字符串的数量没有多大用处 (2认同)

Mar*_*ick 8

这是将 Unix 工具放在管道中的一个很好的用例。

line=5
str="ipsum"
sed -n "${line}p" filename | grep -o -- "$str" | wc -l
Run Code Online (Sandbox Code Playgroud)

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


Ser*_*nyy 7

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
Run Code Online (Sandbox Code Playgroud)

这是如何工作的:

  • 我们运行带有-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
Run Code Online (Sandbox Code Playgroud)

sed+grep

当然,我们不必单独使用脚本语言。sedgrep提供足够的工具来满足我们的需求。由于grep -c我们可以计算匹配行的出现次数,因此我们要做的就是提取我们需要的特定行,并将该行中的所有单词拆分为单独的行。像这样:

$ sed -n  '2{s/ /\n/g;p}' input.txt | grep -c 'word'
3
Run Code Online (Sandbox Code Playgroud)

  • `python -c 'n,w,f=2,"word",open("input.txt");[f.readline()for _ in range(n-1)];print(f.readline() .count(w))'` 将是我个人的建议。 (2认同)

Rav*_*ina 6

awk 解决方案:

awk 'NR==X { print gsub("word",""); }' file
Run Code Online (Sandbox Code Playgroud)
  • X使用您的特定行号更改。
  • 用你想要的词改变“词”。
  • gsub 返回“单词”的替换次数,看起来我们正在计算它。

例子:

$ cat file:
a b c a a d
d e f f f 1
Run Code Online (Sandbox Code Playgroud)

让我们看看在“2”行中有多少个“f”:

$ awk 'NR==2 { print gsub("f",""); }' file
3
Run Code Online (Sandbox Code Playgroud)


ste*_*ver 5

一种方法,在perl

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