Linux文本处理三剑客:grep

在Linux操作系统中,grep、sed、awk被称为文本操作“三剑客”,接下来的几期中,我们将详细介绍grep、sed、awk的基本使用方法,希望能够帮助到有需要的朋友,我会参考官方文档来做翻译理解。今天先讲 grep 的用法,下面正式开始:

grep (Global Regular Expression Print) 命令用于查找文件里符合条件的字符串或正则表达式。

下面是关于 grep 命令的详细介绍,包括参数、用法和示例代码。

grep 命令简介

  • grep 是 Linux/Unix 系统中的一个命令行工具,用于从文件中搜索文本或字符串。
  • 它代表“全局正则表达式打印”(Global Regular Expression Print)。
  • 当我们在 grep 命令后跟搜索字符串或模式时,如果匹配成功,它将显示包含该字符串的所在行,而不会修改现有文件的内容。

1、命令语法

$ grep [选项] 模式 [文件...]
$ grep [选项] [-e 模式 | -f 文件] [文件...]

1.1 语法描述

grep, egrep, fgrep - 打印匹配模式的行

grep 搜索指定的输入文件 (如果没有指定文件,或使用 "-" 作为文件名,则为标准输入) 中包含给定模式匹配的行。默认情况下,grep 打印匹配的行。

此外,grep还有两个变体程序 egrep 和 fgrep 可用。egrep 和 grep -E 功能相同fgrep 和 grep -F 功能相同。直接调用 egrep 或 fgrep 已经过时,但仍可供依赖它们的旧应用程序运行而不进行修改。

2、选项参数:

通用程序信息

--help 打印简要的使用信息,概述这些命令行选项和错误报告地址,然后退出。

-V, --version 将 grep 的版本号打印到标准输出流。所有错误报告都应包含此版本号 (见下文)。

匹配器选择

-E, --extended-regexp 将模式解释为扩展正则表达式 (ERE,见下文)。(-E 由 POSIX 标准指定)

-F, --fixed-strings, --fixed-regexp 将模式解释为由换行符分隔的固定字符串列表,其中任何一个字符串都将匹配。(-F 由 POSIX 标准指定,--fixed-regexp 是过时的别名,请不要在新的脚本中使用它。)

-G, --basic-regexp 将模式解释为基本正则表达式 (BRE,见下文)。这是默认值。

-P, --perl-regexp 将模式解释为 Perl 正则表达式。此功能尚处于高度试验阶段,grep -P 可能会警告您未实现的功能。

匹配控制

-e 模式, --regexp=模式 使用模式作为搜索模式。这可以用于指定多个搜索模式,或者保护以连字符 (-) 开头的模式。(-e 由 POSIX 标准指定)

-f 文件, --file=文件 从文件中获取模式,每行一个。空文件不包含任何模式,因此不会匹配任何内容。(-f 由 POSIX 标准指定)

-i, --ignore-case 忽略模式和输入文件中的大小写区别。(-i 由 POSIX 标准指定)

-v, --invert-match 反转匹配结果,选择不匹配的行。(-v 由 POSIX 标准指定)

-w, --word-regexp 只选择包含完全匹配整个单词的行的匹配。测试方法是,匹配子串必须位于行首,或者之前是非单词构成字符。类似地,它必须位于行尾或后面跟随非单词构成字符。单词构成字符包括字母、数字和下划线。

-x, --line-regexp 只选择那些完全匹配整个行的匹配。(-x 由 POSIX 标准指定)

-y 过时的 -i 的同义词

通用输出控制

-c, --count 隐藏正常输出,而是为每个输入文件打印匹配行的计数。与 -v, --invert-match 选项 (见下文) 配合使用时,则计数不匹配的行。(-c 由 POSIX 标准指定)

--color[=WHEN], --colour[=WHEN] 使用转义序列包围匹配的 (非空) 字符串、匹配行、上下文行、文件名、行号、字节偏移量以及分隔符 (用于字段和上下文行组),以便在终端上以彩色显示它们。 颜色由环境变量 GREP_COLORS 定义。已弃用的环境变量 GREP_COLOR 仍然支持,但其设置不会优先考虑。WHEN 可以是 never (从不)、always (总是) 或 auto (自动)。

-L, --files-without-match 隐藏正常输出,而是打印没有输出的每个输入文件的文件名。扫描将在第一次匹配时停止。

-l, --files-with-matches 隐藏正常输出,而是打印可以输出的每个输入文件的文件名。扫描将在第一次匹配时停止。(-l 由 POSIX 标准指定)

-m NUM, --max-count=NUM 在读取到 NUM 个匹配行后停止读取文件。如果输入是来自普通文件的标准输入,并且输出 NUM 个匹配行,grep 将确保标准输入定位到最后一个匹配行之后的 位置,无论是否存在尾部上下文行。这允许调用进程继续搜索。当 grep 在 NUM 个匹配行之后停止时,它会输出任何尾部上下文行。 当同时使用 -c 或 --count 选项时,grep 不会输出大于 NUM 的计数。当同时使用 -v 或 --invert-match 选项时,grep 在输出 NUM 个不匹配行后停止。

-o, --only-matching 仅打印匹配行的匹配 (非空) 部分,每个部分单独输出一行。

-q, --quiet, --silent 静默模式;不向标准输出写任何内容。如果找到任何匹配项,即使检测到错误,也会立即退出并返回零状态。另请参见 -s 或 --no-messages 选项。 (-q 由 POSIX 标准指定)

-s, --no-messages 隐藏关于不存在或不可读文件的错误消息。可移植性注意:与 GNU grep 不同,第 7 版 Unix 的 grep 不符合 POSIX 标准,因为它缺少 -q, 并且其 -s 选项的行为类似于 GNU grep 的 -q 选项。USG 风格的 grep 也缺少 -q,但它的 -s 选项的行为类似于 GNU grep。 可移植的 shell 脚本应避免使用 -q 和 -s,而应将标准输出和错误输出重定向到 /dev/null。(-s 由 POSIX 标准指定)

输出行前缀控制

-b, --byte-offset 在输出的每一行之前打印输入文件中的 0 基字节偏移量。如果指定了 -o (--only-matching),则打印匹配部分本身的偏移量。

-H, --with-filename 为每个匹配项打印文件名。这是搜索多个文件时的默认设置。

-h, --no-filename 抑制输出中文件名的前缀。这是搜索单个文件 (或仅标准输入) 时的默认设置。

--label=LABEL 将来自标准输入的输入显示为来自文件 LABEL 的输入。这在实现诸如 zgrep 的工具时尤其有用,例如,gzip -cd foo.gz | grep --label=foo -H something。 另请参见 -H 选项。

-n, --line-number 在输出的每一行之前加上其所在输入文件中的 1 基行号。(-n 由 POSIX 标准指定)

-T, --initial-tab 确保实际行内容的第一个字符位于制表符停止位上,使制表符的对齐看起来正常。这对于使用前缀输出到实际内容的选项很有用:-H、-n 和 -b。 为了提高来自单个文件的所有行都从同一列开始的可能性,这也使行号和字节偏移量 (如果存在) 以最小尺寸字段宽度打印。

-u, --unix-byte-offsets 报告 Unix 风格的字节偏移量。此开关使 grep 报告字节偏移量,就像文件是 Unix 风格的文本文件一样,即去掉 CR 字符。这将产生与在 Unix 机器上运行 grep 完全相同的结果。 除非同时使用 -b 选项,否则此选项无效;它对除 MS-DOS 和 MS-Windows 以外的平台没有影响。

-Z, --null 输出零字节 (ASCII NUL 字符) 代替通常跟随文件名后的字符。例如,grep -lZ 在每个文件名后面输出一个零字节,而不是通常的新行。 此选项使输出即使存在包含异常字符 (例如换行符) 的文件名也保持明确。此选项可用于诸如 find -print0、perl -0、sort -z 和 xargs -0 的命令 来处理任意文件名,即使它们包含换行符。

上下文行控制

-A NUM, --after-context=NUM 在匹配行之后打印 NUM 行尾部上下文。在连续的匹配组之间放置包含组分隔符 (在 --group-separator 下描述) 的一行。 与 -o 或 --only-matching 选项配合使用时,此选项无效并会发出警告。

-B NUM, --before-context=NUM 在匹配行之前打印 NUM 行领先上下文。在连续的匹配组之间放置包含组分隔符 (在 --group-separator 下描述) 的一行。 与 -o 或 --only-matching 选项配合使用时,此选项无效并会发出警告。

-C NUM, -NUM, --context=NUM 打印 NUM 行的输出上下文。在连续的匹配组之间放置包含组分隔符 (在 --group-separator 下描述) 的一行。 与 -o 或 --only-matching 选项配合使用时,此选项无效并会发出警告。

--group-separator=SEP 使用 SEP 作为组分隔符。默认情况下,SEP 是双连字符 (--)。

--no-group-separator 使用空字符串作为组分隔符。

文件和目录选择

-a, --text 将二进制文件视为文本文件进行处理;这等同于 --binary-files=text 选项。

--binary-files=TYPE 如果文件的前几个字节表明文件包含二进制数据,则假定该文件属于 TYPE 类型。默认情况下,TYPE 为 binary,grep 通常会输出一行消息, 指出二进制文件匹配,或者如果没有匹配则不输出任何消息。如果 TYPE 为 without-match,则 grep 认为二进制文件不匹配;这等同于 -I 选项。 如果 TYPE 为 text,grep 将二进制文件视为文本文件进行处理;这等同于 -a 选项。警告:grep --binary-files=text 可能输出二进制垃圾, 如果输出是终端并且终端驱动程序将其中の一部解释为命令,则可能会产生负面影响。

-D ACTION, --devices=ACTION 如果输入文件是设备、FIFO 或套接字,则使用 ACTION 处理它。默认情况下,ACTION 为 read,这意味着设备将被读取,就像它们是普通文件一样。 如果 ACTION 为 skip,则设备将被静默跳过。

-d ACTION, --directories=ACTION 如果输入文件是目录,则使用 ACTION 处理它。默认情况下,ACTION 为 read,即像普通文件一样读取目录。如果 ACTION 为 skip,则静默跳过目录。 如果 ACTION 为 recurse,则递归读取每个目录下的所有文件,仅遵循命令行上的符号链接。这等同于 -r 选项。

--exclude=GLOB 跳过文件名匹配 GLOB (使用通配符匹配) 的文件。文件名 glob 可以使用 *、? 和 [...] 作为通配符,以及 \ 来引用通配符或反斜杠字符。

--exclude-from=FILE 跳过文件名匹配 FILE 中读取的任何文件名 glob 的文件 (使用 --exclude 下描述的通配符匹配)。

--exclude-dir=DIR 从递归搜索中排除与模式 DIR 匹配的目录。

-I 将二进制文件视为不包含匹配数据;这等同于 --binary-files=without-match 选项。

--include=GLOB 只搜索文件名匹配 GLOB 的文件 (使用 --exclude 下描述的通配符匹配)。

-r, --recursive 递归读取每个目录下的所有文件,仅遵循命令行上的符号链接。这等同于 -d recurse 选项。

-R, --dereference-recursive 递归读取每个目录下的所有文件。遵循所有符号链接,与 -r 不同。

其他选项

--line-buffered 对输出使用行缓冲。这可能会导致性能下降。

-U, --binary 将文件视为二进制文件。默认情况下,在 MS-DOS 和 MS-Windows 下,grep 通过查看从文件中读取的前 32KB 内容来猜测文件类型。 如果 grep 决定该文件是文本文件,它会从原始文件内容中去除 CR 字符 (使使用 ^ 和 $ 的正则表达式能够正确工作)。指定 -U 会 否决这种猜测,导致所有文件都被读取并逐字传递给匹配机制;如果文件是文本文件,每行末尾都有 CR/LF 对,这将导致一些正则表达式失败。 此选项仅在 MS-DOS 和 MS-Windows 平台上有效。

-z, --null-data 将输入视为一组行,每行由零字节 (ASCII NUL 字符) 而不是换行符终止。与 -Z 或 --null 选项类似,此选项可以与诸如 sort -z 的命令一起使用 来处理任意文件名。

3、正则表达式

正则表达式是描述一组字符串的模式。正则表达式通过使用各种运算符组合较小的表达式,类似于算术表达式来构造。

grep 理解三种不同的正则表达式语法版本:“基本”、“扩展”和“perl”。在 GNU grep 中,基本和扩展语法之间可用功能没有区别。在其他实现中, 基本正则表达式功能较弱。以下描述适用于扩展正则表达式;之后总结了基本正则表达式的差异。Perl 正则表达式提供了额外的功能, 并在 pcresyntax(3) 和 pcrepattern(3) 中进行了说明,但并非所有系统都可用。

基本的构建块是匹配单个字符的正则表达式。大多数字符,包括所有字母和数字,都是匹配它们自己的正则表达式。任何具有特殊含义的元字符都可以通过在其前面加上反斜杠进行转义。

句点 . 匹配任何单个字符。

字符类别和方括号表达式

方括号表达式是包含在方括号 [] 内的字符列表。它匹配列表中的任何单个字符;如果列表的第一个字符是脱字符 ^,则它匹配列表中之外的任何字符。 例如,正则表达式 [0123456789] 匹配任何单个数字。

在方括号表达式内,范围表达式由连字符分隔的两个字符组成。它匹配介于这两个字符之间的任何单个字符 (包含),使用区域设置的排序顺序和字符集。 例如,在默认 C 区域设置中,[a-d] 等于 [abcd]。许多区域设置按字典顺序对字符进行排序,并且在这些区域设置中,[a-d] 通常不等于 [abcd]; 例如,它可能等同于 [aBbCcDd]。要获取方括号表达式的传统解释,可以通过将 LC_ALL 环境变量设置为值 C 来使用 C 区域设置。

最后,方括号表达式中预定义了某些命名的字符类,如下所示。它们的名称不言自明,它们分别是 [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:], 和 [:xdigit:]. 例如,[[:alnum:]] 表示当前区域设置中数字和字母的字符类。 在 C 区域设置和 ASCII 字符集编码中,这与 [0-9A-Za-z] 相同。(请注意,这些类名中的括号是符号名称的一部分,必须包含在除 分隔方括号表达式的括号之外。) 大多数元字符在方括号表达式内失去其特殊含义。要包含一个文字 ],请将其放在列表中 的第一个位置。类似地,要包含一个文字 ^,请将其放在除第一个之外的任何位置。最后,要包含一个文字 -,请将其放在最后。

锚定

脱字符 ^ 和 美元符号 $ 是元字符,分别匹配行首和行尾的空字符串。

反斜杠字符和特殊表达式

符号 < 和 > 分别匹配单词开头和结尾的空字符串。符号 \b 匹配单词边缘的空字符串,\B 匹配空字符串,前提是不在单词边缘。 符号 \w 是 [[:alnum:]] 的同义词,\W 是 [^[:alnum:]].

重复

正则表达式后面可以跟随以下几种重复运算符之一:

? 前面的项目可选,最多匹配一次。
* 前面的项目将匹配零次或多次。
+ 前面的项目将匹配一次或多次。
{n} 前面的项目精确匹配 n 次。
{n,} 前面的项目匹配 n 次或更多次。
{,m} 前面的项目最多匹配 m 次。这是 GNU 扩展。
{n,m} 前面的项目至少匹配 n 次,但不得超过 m 次。

连接

两个正则表达式可以连接起来;生成的正则表达式匹配通过连接两个子字符串形成的任何字符串,这两个子字符串分别匹配连接的表达式。

交替

可以使用中缀运算符 | 连接两个正则表达式;生成的正则表达式匹配任何匹配任一备选表达式的字符串。

优先级

重复运算符的优先级高于连接运算符,连接运算符的优先级又高于交替运算符。整个表达式可以用括号括起来,以覆盖这些优先级规则并形成子表达式。

反向引用和子表达式

反向引用 \n,其中 n 为单个数字,匹配先前由正则表达式的第 n 个带括号的子表达式匹配的子字符串。

基本正则表达式 vs 扩展正则表达式

在基本正则表达式中,元字符 ?, +, {, |, (, 和 ) 失去其特殊含义改用反斜杠版本 ?, +, {, |, (, 和 )。

传统的 egrep 不支持 { 元字符,一些 egrep 实现支持 {,因此可移植脚本应避免在 grep -E 模式中使用 {,而应使用 [{] 匹配文字 {.

GNU grep -E 尝试通过假设 { 在无效间隔规范的开头不是特殊的来支持传统用法。例如,命令 grep -E '{1' 搜索双字符字符串 {1,而不是报告正则表达式中的语法错误。POSIX 允许这种行为作为扩展,但可移植的脚本应该避免它。

4、常用选项和示例

  1. 在文件中搜索单词或字符串
    $ grep nobody /etc/passwd
    
    • 示例:在文件 /etc/passwd 中搜索用户名为 nobody 的行
  2. 多文件中的搜索模式
    $ sudo grep linuxtechi /etc/passwd /etc/shadow /etc/gshadow
    
    • 示例:在 /etc/passwd/etc/shadow/etc/gshadow 文件中搜索用户名为 linuxtechi 的行
  3. 打印与模式匹配的文件名
    $ grep -l 'root' /etc/fstab /etc/passwd /etc/mtab
    
    • 示例:列出包含单词 root 的文件名
  4. 显示带有行号的输出行
    $ grep -n 'nobody' /etc/passwd
    
    • 示例:显示与模式 nobody 匹配的行及其行号
  5. 反转模式匹配
    $ grep -v 'nobody' /etc/passwd
    
    • 示例:显示与模式 nobody 不匹配的行
  6. 打印以特定字符开头的所有行
    $ grep ^backup /etc/passwd
    
    • 示例:显示文件 /etc/passwd 中以 backup 开头的行
  7. 打印以特定字符结尾的所有行
    $ grep bash$ /etc/passwd
    
    • 示例:列出 /etc/passwd 中以 bash 结尾的所有行
  8. 递归搜索模式
    $ sudo grep -r nobody /etc
    
    • 示例:递归搜索 /etc 文件夹中的模式 nologin
  9. 打印文件中的所有空行
    $ grep '^$' /etc/sysctl.conf
    
    • 示例:打印 /etc/sysctl.conf 中的所有空行
  10. 搜索时忽略字母大小写
    $ grep -i IP_Forward /etc/sysctl.conf
    
    • 示例:在 sysctl.conf 文件中搜索字符串 IP_Forward
  11. 匹配多个模式
    $ grep -e nobody -e mail /etc/passwd
    
    • 示例:在 /etc/passwd 中搜索同时包含 nobodymail 的行
  12. 从文件中获取模式
    $ grep -f grep_pattern /etc/passwd
    
    • 示例:从文件中获取模式并搜索
  13. 计算与模式匹配的行数
    $ grep -c false$ /etc/passwd
    
    • 示例:计算 /etc/passwd 中以 false 结尾的行数

14.打印模式匹配前后的 N 行

$ grep -B 4 "games" /etc/passwd
$ grep -A 4 "games" /etc/passwd
$ grep -C 2 "games" /etc/passwd
  • (a) 打印在模式匹配之前的四行
  • (b) 打印在模式匹配之后的四行
  • © 打印在模式匹配之前的两行和之后的两行

15.使用正则表达式进行高级搜索

$ grep '^[0-9]' /etc/passwd
  • 示例:搜索以数字开头的行

16.递归搜索目录并显示匹配行的文件名和行号

$ sudo grep -rHn 'nologin' /etc
  • 示例:在 /etc 目录中递归搜索模式 nologin 并显示文件名和行号

17.将搜索结果写入文件

$ grep 'root' /etc/passwd > output.txt
  • 示例:将搜索结果写入文件 output.txt

18.使用 -E 选项进行扩展正则表达式搜索

$ grep -E 'root|admin' /etc/passwd
  • 示例:搜索包含 rootadmin 的行

19.使用 -o 选项仅打印匹配的部分

$ grep -oE '^[^:]+'
  • 示例:从 /etc/passwd 中提取用户名

20.使用 -q 选项进行静默搜索

$ grep -q 'nobody' /etc/passwd && echo "Pattern found" || echo "Pattern not found"
  • 示例:检查文件中是否存在模式 nobody

这些示例应该能帮助你更好地理解 grep 命令的用法和功能。先写这多吧,主要还是要多练习,练习的话,用子系统Ubuntu就可以。

 如果您觉得有些用处,欢迎在评论区留言,关注。谢谢您的阅读!

 往期学习笔记:

Windows系统开启Linux子系统(Ubuntu)

Linux常用命令(目录操作命令)

Linux常用命令:文件的创建、复制、移动、查找和删除命令

Linux常用命令:文本文件的查看与编辑

Linux常用命令:文本文件的拼接与分割

Linux常用命令:文件的权限管理

Linux常用命令:文件的下载、压缩与解压

Linux常用命令:常见的操作符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TiYong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值