Contents

在Linux中计算文本文件中字符的出现次数

1. 概述

在本教程中,我们将学习使用 Linux 命令查找文本文件中特定字符的计数。

我们假设您对常用的 Linux 命令有基本的了解,包括 grepawktrwc

我们还假设我们的输入文件blogdemo.txt中有一些虚拟数据:

$ cat blogdemo.txt 
"I Love Blogdemo!!!"
"Blogdemo is great!!!"

对于本教程的其余部分,我们将使用blogdemo.txt进行演示。

2. 使用 grep 命令

*grep *命令在输入文件中搜索给定的模式。

让我们通过命令使用 grep获取字符数:

$ grep -o 'e' blogdemo.txt | wc -l
4

在这里,我们正在寻找文件blogdemo.txt中出现的字符*“e”-o*选项在单独的输出行 中打印匹配的部分。

现在,我们使用管道运算符将grep命令的输出传递给wc 命令。最后,wc命令中的 -l选项计算输入字符串中的总行数。

2.1. 不区分大小写的搜索

grep命令支持*-i* 选项来执行不区分大小写的搜索:

$ grep -o -i 'l' blogdemo.txt | wc -l
3

2.2. 使用多个输入文件

**我们可以将多个输入文件传递给 grep 命令。**然后它将查看所有文件并返回在每个文件中找到的字符数的总和:

$ cat > dummy.txt
This is dummy text.
$ grep -o -i 'e' blogdemo.txt dummy.txt | wc -l
5

在这里,我们创建了一个新文件 dummy.txt并对文件blogdemo.txtdummy.txt执行了字符计数操作。

请注意,我们将两个文件作为参数传递给了 grep 命令。输出包括两个文件的字符数之和。

3. 使用 tr 命令

tr  是一个命令行实用程序,用于执行基于字符的转换

我们可以结合使用两个选项*-c* 和*-d*来获取字符数:

$ tr -c -d 'l' < blogdemo.txt | wc -c
2

让我们首先了解上述命令中使用的选项。

  • -c:此选项将采用集合的补充
  • -d:它将删除集合中提到的所有字符

**集合被定义为字符串。**在我们的例子中,集合是一个只有一个字符的字符串,’l’

现在,当我们将-c 和*-d* 选项组合在一起时,它将删除除我们在集合中提到的字符之外的所有字符。**

结果字符串将使用管道运算符传递给wc命令。wc命令中的*-c*选项 将返回总字符数。

3.1. 不区分大小写的搜索

我们可以通过在集合中同时添加大写和小写字符来执行不区分大小写的搜索:

$ tr -cd 'lL' < blogdemo.txt | wc -c
3

4. 使用 awk 命令

awk是一种数据驱动的编程语言,它获取输入数据,对其进行处理,然后返回所需的输出。

与我们目前讨论的两种方法不同,这种方法有点难以理解。

让我们看一下命令并了解它是如何工作的:

$ awk -F 'e' '{s+=(NF-1)} END {print s}' blogdemo.txt 
4

awk实用程序的默认字段分隔符是空格。但在这里我们使用*-F选项**将字段分隔符更新为“ e ” 。这将在每次出现’e’*时分隔我们的数据。

为我们的数据集形成的组将是*’”I Lov’* ,  ‘Blogd’ , ‘mo!!!”’对于第一行和’”Blogd’ , ‘mo is gr’ , ‘at!!!”’ 对于第二行。

现在,这个片段*{s+=(NF-1)} END {print s}* 将计算生成的数据的所有部分并从中减去一个(因为一个字符匹配会将数据分成两部分。)以获得所需的每行中的字符计数。这个计数将被添加到每一行,最后,我们得到整个文件的总字符出现次数。

5. 性能比较

到目前为止,我们讨论的所有三种方法都执行相同的操作。但区别在于它们处理数据的方式。

现在,对于一个小字符串或者一个小文件,这些命令执行的时间几乎是一样的。但真正的区别是当我们的文件太大时。

让我们在一个 1.1GB 的文件上运行所有三个命令,并监控每个命令所用的时间:

$ ls -lah large.txt 
-rw-r--r--. 1 root root 1.1G Jun 12 10:53 large.txt
$ time grep -o 'e' large.txt | wc -l
82256735
real	0m40.733s
user	0m39.649s
sys	0m0.714s
$ time tr -c -d 'e' &lt; large.txt | wc -c
82256735
real	0m2.542s
user	0m1.892s
sys	0m0.433s
$ time awk -Fe '{s+=(NF-1)} END {print s}' large.txt 
82256735
real	0m11.080s
user	0m9.589s
sys	0m0.933s

tr命令是获取大文件字符数的三个命令中最快的。