我知道我可以使用 wc 返回文件中的总字数(和行数):
wc <filename>
有没有办法返回文件特定行上特定字符串的计数,如下所示:
wc <filename> -<flag> <line number> -<flag> <string>
答案1
这需要分三步完成:
选择行号 N (示例使用第 42 行):
sed '42!d'
在该行中搜索特定模式(这里是字符串/正则表达式
hello
)的所有出现,并分别打印它们:grep -o 'hello'
计算匹配次数:
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
重定向到stdin
python 解释器的流中<
。因此我们需要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>