在Linux中的目录中找到文本文件
1. 概述
有时,我们只想处理文本文件。对于 Windows 等操作系统,我们可以通过查看文件名中的扩展名轻松确定文件的类型。例如,扩展名为“.txt”的文件是纯 ASCII 文本文件。但对于 Linux 来说情况并非如此。
Linux 将多种文件归类为文本文件,因此要判断一个文件是否为文本类型,必须要检查文件的内容,而 file 命令正是胜任这项工作的工具 。file命令将文件大致分为文本文件、二进制文件或数据文件。所以在本教程中,我们将学习如何使用file命令来识别目录中的所有文本文件。
2. 文本文件的类型
文本文件是包含可打印字符和少量常用控制字符(如换行符“\n”、回车符“\r”和制表符空格“\t”)的任何文件。另一方面,像大多数数据或可执行二进制文件这样的非文本文件由不可打印的字符组成。
现在,让我们看看如何使用file命令列出目录中所有文件的类型:
$ file *
filename1: ASCII text
Dirname1: directory
filename3.perf: data
filename4.py: Python script, ASCII text executable
该命令列出目录中的所有文件及其内容的信息描述。有两种类型的文件在其描述中包含“文本”。
2.1. 纯文本文件
仅包含可打印的 ASCII 字符或 Unicode UTF-8 字符和一些通用控制字符的文件是纯文本文件。文件 命令将此类文件分类为“ASCII 文本”或“UTF-8 Unicode 文本”文件。
包含 Unicode 编码 UTF-16 或 UTF-32 的文件由可打印文本组成,但在打印前需要翻译。因此,文件命令给出的描述包含短语“字符数据”而不是“文本”。
2.2. 源代码或脚本文件
许多编程或脚本语言的源代码文件也是文本文件。比如shell脚本文件、python脚本文件、C代码文件、Java源文件都是文本文件。此类源代码文件包含带有一些通用控制字符的 ASCII 可打印文本。
3. 查找所有文本文件
当我们只需要知道目录中的所有文本文件(包括子目录中的文件)时,可能会有多种情况。一种这样的情况是当我们想要复制所有源文件,而不是编译的中间文件和可执行文件时。这确保了当我们复制一个项目时,数据量比复制所有内容时更易于管理。
另一种可能的情况是当我们想要在所有源文件或脚本文件中搜索某个文本短语时。
在这种情况下,file命令就派上用场了。
3.1. 在当前目录中
如果我们只对当前目录中的文件感兴趣,那么该命令毫不费力。我们可以使用一个简单的命令快速列出当前目录中的所有文本文件:
file * | grep ":.* text"
**file *命令打印文件名列表,后跟当前目录中所有文件的文件类型描述。**随后的 grep 命令过滤所有带有“ASCII 文本”或“UTF-8 Unicode 文本”作为文件类型描述的一部分的文件。表达式“:.*”确保仅在文件类型描述中搜索子字符串“text”,而不是在文件名中搜索。换句话说,该表达式的意思是“在文件命令输出中搜索 :后跟任意数量的字符“.*”,然后是子字符串“text”。
在极少数情况下,某些文件包含字符“:”作为其名称的一部分,我们可以使用文件命令的*-F参数来使用“:”字符以外的其他字符作为分隔符。需要相应地修改grep*命令,将用作分隔符的另一个字符替换为“:”。
输出文件列表包括纯文本、脚本、格式化文本和源代码文件。
3.2. 在搜索中包括子目录
如果我们想查找当前目录中的所有文本文件,包括其子目录,那么我们必须使用 Linux *find *命令来扩充命令:
find . -type f -exec file {} \; | grep ":.* ASCII text"
在这里,参数“。” 表示“查看当前目录及其所有子目录”。参数*-type f使 find 只考虑文件,而不考虑目录。参数 -exec file {} ; 表示对find提供的所有文件执行file命令。然后将find命令的输出通过管道传递给grep*命令。然后,grep命令过滤所有描述中包含文本“ASCII 文本”的文件。
3.3. 仅查找纯文本文件
有时,我们的兴趣只在于找出纯文本文件。换句话说,我们要排除包含源代码、脚本或格式化文本(如 XML 或 HTML)的文件。该命令是:
$ file -i * | grep " text/plain;"
file1: text/plain; charset=us-ascii
file2: text/plain; charset=utf-8
由于*-i*标志,file命令将文件类型描述打印为 mime 类型字符串。“文本/纯文本;” 其他文本文件如“C 源代码”或“Python 脚本文件”的描述中没有。因此,要特别过滤纯文本文件,我们可以使用此命令。