Netwrix 1Secure 提供跨数据和身份的统一可见性——免费试用14天,享有完全访问权限。开始免费试用

资源中心博客

PowerShell Grep 命令

PowerShell Grep 命令

Aug 25, 2025

Unix/Linux grep 命令是一款用途广泛的文本搜索工具,用于日志分析、代码扫描和系统诊断。它支持不区分大小写的搜索、递归目录扫描、反向匹配、行号,以及诸如前瞻(lookahead)和后顾(lookbehind)等高级正则表达式模式。在 Windows 上,PowerShell 的 Select-String 则起到对应作用,使您能够在文件、数据流和自动化脚本中快速进行模式匹配。

Grep(Global Regular Expression print)命令是 Unix/Linux 系统中的强大文本搜索工具。Grep 接收诸如正则表达式或字符串之类的模式,然后在一个或多个输入文件中搜索包含预期模式的行。Grep 命令可广泛用于文本搜索与过滤、日志分析、代码扫描、配置管理、数据提取等。在软件开发中,文本搜索用于代码导航、重构、调试、错误诊断、安全威胁扫描、版本控制以及代码审查。文本搜索工具能够显著减少开发人员查找特定函数、变量或错误消息所花费的时间。在系统管理中,文本搜索在日志分析与监控、安全与威胁检测、数据处理和自动化等任务中非常好用。像 grep、awk 和 sed 这样的文本处理工具用于扫描日志,以分析认证事件、特定异常,并通过严重级别、时间戳或关键词对日志进行筛选,帮助管理员发现故障、安全漏洞以及性能问题。在这篇博客中,我们将全面探讨 Grep 的功能、示例与使用场景。通过使用正则表达式匹配来搜索文件和输入中的文本模式,Select-String 也可以在 Windows 中作为 PowerShell 对应于 grep 的用法。

Netwrix Auditor for Active Directory

全面了解您的 Active Directory 中正在发生的情况

基本语法与用法

grep 命令是在 Unix/Linux 中搜索文本模式、用于文本筛选与分析的强大工具。下面是包含模式、文件和选项的基本命令结构。

grep [options] pattern [file…]

  • 模式: 要搜索的正则表达式文本。
  • 文件: 要在其中进行搜索的文件或文件集。
  • 选项: 用于改变 grep 行为的修饰符或开关。选项通常前面带有连字符(-)。

以下是一些最常用的选项。

  • -i: 在搜索模式和数据中忽略大小写。例如,下面的命令将搜索“hello”、“HELLO”、“Hello”等。

grep -i “hello” file.txt

  • -v: 反转搜索匹配结果,显示与指定模式不匹配的行。例如,下面的命令会显示不包含“hello”的行。此选项有助于查找不符合特定条件的行。

grep -v “hello” file.txt

  • -n: 在每一行匹配条件的内容之前显示行号,并有助于报告共享。例如,下面的命令会显示单词“function”出现的位置对应的行号。

grep -n “function” file.txt

  • -r: 递归搜索目录,即在目录及其子目录中的所有文件里查找该模式。
  • –color: 在输出中突出显示匹配的字符串。例如,下面的命令会在输出中高亮显示 “hello”。

grep –color “hello” file.txt

  • -l: 只列出包含至少一个匹配项的文件名。

grep -l “starting” *.log

a screenshot of a command line that says

平台兼容性

Grep 在 Unix/Linux 系统的命令行中默认集成,并且按预期以一致的方式运行。它支持正则表达式、支持管道(piping),并能与其他 Unix/Linux 工具无缝集成。Windows 系统中可通过 Windows subsystem for Linux (WSL) 使用 Grep,从而让用户无需虚拟机的开销即可在 windows 上直接运行 GNU/Linux 环境。此外,windows 还提供了多种原生版本的 grep,这些都是编译后的独立版本,可直接在 windows 上运行,例如 Git Bash、Gnuwin32。

虽然 grep 的设计目标是在各个平台上保持一致,但在不同平台上使用时,需要注意一些差异和限制。

  • 行结束符: Unix/Linux 系统使用 ‘\n’ 作为行结束符,而 windows 使用 ‘\r\n’。
  • 路径表示: 文件系统在 Unix/Linux 与 windows 之间的行为不同。windows 路径使用反斜杠 ‘\’,而不是 Unix/Linux 中使用的 ‘/’。
  • 字符编码: 不同平台使用不同的默认字符编码,尤其是在处理非 ASCII 文本时。
  • 命令行选项: 大多数常见的 grep 选项在各个平台上都受支持。但在不同平台上,grep 的支持可能会有限,例如在 Windows 上的管道(piping)支持可能较为有限。

grep 实战示例

简单的文本搜索

在下面的示例中,我们在日志文件中搜索字符串“deployment”。

Grep “deployment” logemail.log

a screenshot of a command line window with a lot of text on it .

在下面的示例中,我们使用选项 -i 搜索字符串“starting”,该选项会忽略大小写差异。

grep -i “starting” logemail.log

a screenshot of a command line window showing a list of commands .

而如果我们不使用 -i 选项,则会在整个文件中匹配精确的字符串,例如 grep “Starting” logemail.log 这条命令会搜索 Starting,并忽略诸如“starting”或“STARTING”之类的匹配项,或任何其他对字符串“starting”大小写敏感的组合。

递归搜索

有时文件分散在不同的目录中,需要在多个文件和目录上运行模式搜索。使用 -r 选项并结合 --include 和 --exclude 进行 grep 递归搜索,可以提供一个快速的解决方案。在下面的命令中,我们会在当前目录及其子目录中的所有 .log 文件里递归搜索模式“starting”,并且只打印匹配到该模式的日志文件中的第一条记录。我们当前位于“Documents”目录,其中包含子目录“office”和“project”。

grep -r “starting” –include=”*.log” -m1 –color=always

a screenshot of a command line window that says replication service is starting .

在下面的示例中,我们排除所有日志文件,并在目录“Documents”及其子目录中的所有文件里递归搜索字符串“starting”。

Grep -r “starting” –exclude=”*.log”

a black screen with red text that says data service is starting

反转匹配结果

我们可以使用 -v 选项来反转搜索结果。这样,我们就可以搜索某个字符串,并找到所有不包含该字符串的行。下面的示例中,我们使用选项 -v 查找不包含“starting”的所有行,也就是查找搜索字符串“starting”对应的反向结果。

Grep -v “starting” logmail.log

Image

行号与上下文输出:

在文件中查找模式时,查看包含该搜索模式的精确行号很有用;有时,将搜索匹配项周围的上下文一并呈现会更好。比如在浏览日志文件以查找异常时,最好在搜索字符串前后各包含一些行,让它们出现在搜索结果中。下面的示例中,我们使用 -n 选项来打印与匹配模式对应的行号。

Grep -n “starting” logemail.log

a screenshot of a command line window showing that the email service is starting .

使用选项 -A,我们可以打印匹配结果之后的行;使用选项 -B,可以打印匹配结果之前的几行;使用 -C,则可以在搜索结果的前后各打印一些行。在下面的示例中,我们使用 -A、-B 和 -C 来显示搜索结果前后的行。

grep -A 2 “starting” logemail.log

a black screen with a lot of text on it .

grep -B 2 “starting” logemail.log

a screenshot of a command line window showing a starting log .

Grep -C 1 “starting” logemail.log

a black screen with a lot of text on it .

在 grep 中使用正则表达式

正则表达式是用于定义搜索模式的一串字符,常用于字符串匹配与处理。下面是一些基本的正则表达式。

  • 点号(.): 匹配除换行符以外的任意单个字符。即: “c.t” 可匹配 cat、cot、crt、cet 等。
  • 星号(*): 匹配前一个字符出现 0 次或多次。即: “c*t” 可匹配 ct、cat、caat、caaaat 等。
  • 插入符(^): 匹配开头位置。也就是说:^an 只有在位于行首时才会与 an 匹配。
  • 美元符号($): 匹配行尾位置。也就是说:$finished 只有在位于行尾时才会与 finished 匹配。
  • 竖线(|): 竖线在正则表达式中相当于逻辑 OR。也就是说:(apple | banana) 会匹配该行中的 apple 或 banana。
  • 转义字符 (\): 用于转义特殊字符,例如 \ 。匹配字面量的句点。

Grep 支持正则表达式;它使用基本正则表达式(BRE),同时也支持使用 -E 标志的扩展正则表达式(ERE)以及使用 -P 标志的 Perl 兼容正则表达式(PCERE)。扩展正则表达式提供更多元字符,例如 +(一个或多个匹配)、?(零次或一次匹配)、|(逻辑 OR)、{}(分组模式),从而进行更高级的模式搜索。Perl 兼容正则表达式功能最强且最灵活,提供更多选项,例如前瞻 (?=)、后顾 (?<!)、非捕获组 (?:pattern) 等。

在下面的示例中,我们会在文件中查找完整单词,并使用字符串匹配来展示 grep 命令的变体。

  • Grep “end” log.txt,将匹配 end 这个单词的所有可能变体。
  • grep -w “end” log.txt,将只匹配整个单词 “end”。
  • grep “\bend\b” log.txt, 将仅使用正则表达式匹配整个单词“end”。
  • Grep “\bend” log.txt, 会匹配行首的字符串“end”。
a black screen with a bunch of text on it .

在下面的示例中,我们使用不同的变体来匹配文件“log.txt”中的数字。

  • grep “[0-9]” log.txt, 将查找包含任意数字的所有行。
  • grep “[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}” log.txt , 将在指定文件中查找电话号码。
  • grep -E “[0-9]{2,4}” log.txt , 将查找包含连续数字 2 位、3 位或 4 位的行。
a black screen with a bunch of text on it .

在下面的示例中,我们会在文件 log.txt 中查找空白(whitespace)。

  • grep “^[[:space:]]” log.txt 将查找行开头的空格。
  • grep “^[[:space:]]” log.txt 将查找行末的空格。
a black screen with white text that says this line starts with space

使用 grep 命令可以查找诸如 IP 地址和电子邮件之类的复杂模式。在下面的示例中,我们使用正则表达式来查找 IP 地址。

grep -E “\(?[0-9]{3}\)?[-. ]?[0-9]{3}[-. ]?[0-9]{4}” log.txt

a black screen with a lot of text on it

在下面的示例中,我们使用正则表达式来查找电子邮件地址。

grep -E “[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}” log.txt

a black screen with a few lines of text on it

高级正则表达式技巧(例如,使用 -P 的前向查看和后向查看)

前向查看(lookahead)和后向查看(lookbehind)是一种强大的技术,可根据其周围的模式来查找模式。例如,如果我们想在日志文件中搜索“error”,但前提是该行中也有应用程序正在启动的信息,则只能在这种情况下进行搜索。前向查看有两种类型:正向查看(Positive lookahead)和负向查看(Negative lookahead)。

  • 正向前瞻(Positive lookahead,?=…)确保括号内的模式出现在当前位置之后,但不会将当前位置包含在匹配结果中。也就是说,如果日志行中“starting”紧跟在“error”后面,我们就可以搜索“error”。
  • 负向前瞻(Negative lookahead,(?!…)确保括号内的模式不会出现在当前位置之后。也就是说,我们可以搜索模式“starting”,但不能是后面紧跟模式“error”的情况。

grep -P “error(?= starting)” log.txt

grep -P “starting(?!= error)” log.txt

a computer screen shows an error starting the application after it crashed

lookbehind 有两种类型:正向后顾(Positive lookbehind)和负向后顾(Negative lookbehind)。

  • 正向后顾 (?<=…),确保括号内的模式出现在当前的位置之前,但不包含在匹配结果中。
  • 负向后顾 (?<!…),确保括号内的模式不出现在当前的位置之前。

Grep -P “(?<=starting )error” log.txt

grep -P “error)?=.*starting)” log.txt

a computer screen shows a starting error detected in the process

grep 的高级功能

组合多个模式

grep 命令也允许我们将多个模式用于搜索;可以使用 -e 选项来组合多个模式。在下面的示例中,我们在同一个文件中搜索两种不同的模式。

Grep -e “starting” -e “error” log.txt

此外,我们还可以使用 -e 在多个文件中查找多个模式:例如在 log.txt 文件中查找“starting”,在 logemail.log 中查找“error”。

grep -e “starting” -e “error” log.txt logemail.log

a screenshot of a terminal window showing a starting error detected in the process .

输出自定义

您可以使用 –color 选项在输出中突出显示搜索到的模式,无论是在控制台打印还是将输出重定向到文件。

  • –color=auto 会根据输出是否将发送到终端来决定是否使用颜色
  • –color=always:始终使用颜色,即使输出正在重定向到文件。
  • –color=never:永不使用颜色。

grep –color=auto “error” log.txt

grep –color=always “error” log.txt

grep –color=never “error” log.txt

a screenshot of a command line window showing the ending of the last line trailed an error .

我们可以使用 -q 选项来修改 grep 命令的输出,使其安静地运行。使用 -q 选项不会打印所有匹配的行,只会输出自定义消息。在下面的示例中,我们在 log.txt 文件中查找模式 “error”,并打印 “error found”。

grep -q “error” log.txt && echo “error found!” || echo “No error found”

if grep -qi “error” log.txt; then echo ” error found”; fi

a screenshot of a command line that says error found

性能优化

grep 读取大文件时不会将文件全部加载到内存中;不过,我们可以通过一些额外的技巧进一步提升其性能。

  • 过度使用正则表达式: 正则表达式(Regex)计算开销较大。在需要查找精确的字面字符串时,可以使用固定字符串的 grep,避免正则计算带来的额外开销。
  • 使用 –mmap: 如果在文件内部进行大量随机访问,可以使用 –mmap 来启用内存映射文件访问。
  • 并行处理: 如果我们的任务允许将大文件拆分,并在不同部分上运行多个 grep 进程,那么这有助于性能优化:它会运行多个 grep 进程实例,之后我们可以合并结果。
  • 限制输出: 我们可以限制输出,只显示搜索到的第一个或第二个匹配项;或者抑制输出,只检查模式是否存在。

Grep 命令默认会对输出进行缓冲,这可能会在通过管道将命令串联时延迟实时处理。使用 “–line-buffered” 选项可以强制在每次匹配时立即输出。下面的示例中,我们将 tail 和 grep 进行串联,以持续监控日志文件,并按行输出匹配的模式 “error”。

Tail -f log.txt | grep –line-buffered “error”

a computer screen shows an error starting the application after it crashed

基于文件的模式匹配

我们可以用 grep 命令创建一个用于搜索的模式文件,然后使用 –file 选项从文件中搜索多个模式。在下面的示例中,我们创建了一个包含模式“starting”、“application”和“INFO”的文件 pattern.txt,并在 grep 命令中使用 –file 来在文件 logemail.log 中搜索这些模式;同时使用 -m2 选项,以显示两次出现的结果。

grep –file=pattern.txt -m2 logemai.log

a screenshot of a command line window on a computer .

grep 的管道和重定向

我们可以将 grep 命令与其他命令串联,以适应不同的场景。在下面的命令中,我们使用进程状态(ps)命令获取所有进程,并将结果通过管道传递给 grep,只输出 python 进程。

ps aux | grep python

a black screen with a lot of text on it

在下面的示例中,我们会获取当前目录中的所有文件和文件夹,然后使用 grep 命令仅筛选日志文件。

ls -a | grep ‘\.log$’

a black screen with a few lines of text on it

在下面的示例中,我们使用 ps、grep 和 awk 命令来打印正在使用 Python 进程的用户名称。

ps aux | grep python | awk ‘{print $1}’

a black background with a lot of text on it .

在下面的示例中,我们会在 erros.txt 文件中查找模式“error”,并使用 sed 命令将所有“error”出现的位置突出显示为“Alert”。

grep “error” erros.txt | sed ‘s/error/ALERT/’

a black screen with a lot of text on it

在以下示例中,我们会在文件 log.txt 中搜索模式“error”,并将输出重定向到当前目录中的另一个文件 erros.txt。第一个命令会覆盖 errors.txt 文件中的输出;第二个命令会将 grep 在 error.txt 文件中的输出追加写入。

grep “error” log.txt > errors.txt

grep “error” logemail.log >> errors.txt

a screenshot of a command line window showing two lines of text .

在下面的命令中,我们使用 tee 将 grep 的输出写入到 erros.txt 文件,同时也在控制台上打印输出。

grep “starting” logemail.log | tee errors.txt

a black screen with a lot of text on it .

真实世界的用例与示例

日志文件分析与过滤

(如上已给出大量示例)

从数据文件中进行文本处理与提取

(如上提供了很多示例)

我们可以使用 netstat 和 ss 命令获取不同端口的状态,以及正在监听这些端口的进程。结合 grep 进一步缩小范围,也可以筛选到特定端口。下面的示例中,我们使用 netstat 和 ss 命令来获取正在监听不同端口的所有进程。

netstat -lntp | grep “LISTEN”

a black screen with a list of processes on it .

ss -lntp | grep “LISTEN”

a black screen with a list of numbers and letters on it .

我们可以将 grep 命令与其他命令结合使用,以获取系统信息并快速搜索不同的配置项。下面的示例中,我们将检查不同的系统信息,这对诊断用途很有帮助。

ps aux | grep “CPU” # 用于检查 CPU 统计信息。

df -h | grep “/dev/sd” # 用于检查磁盘使用情况。

ip a | grep “inet” # 用于查找 IP 地址

a black screen with a lot of text on it .

自定义并为 grep 设置别名

我们可以为带有不同选项的 grep 命令定义别名,然后在搜索模式时使用这些别名,而不是每次都使用带选项的 grep 命令。

alias g=’grep’

alias gi=’grep -i’

alias gr=’grep -r’

alias gc=’gr -n –color=auto’

定义这些别名之后,我们就可以仅使用别名来进行模式搜索。

g “error” -m1 log.txt

gi “error” -m1 log.txt

gr “error” -m1 log.txt

gc “error” -m1 log.txt

a black screen with a bunch of text on it .

我们可以编写一个函数来读取前 10 条系统日志。在下面的示例中,我们编写了一个函数 “find_error”,用于读取位置为 “/var/log/systemlog” 的 syslog 文件,并输出包含模式 “error” 的最后 10 行。

find_errors{

grep -I “error” /var/log/syslog | tail -n 10

}

Find_errors

a screenshot of a command line window showing a bunch of errors .

我们使用 tail、grep 和 tee 命令来搜索 syslog,并使用“error”关键字筛选错误;然后在控制台上显示输出,并将其添加到日志文件中。

tail -f /var/log/syslog | grep –line-buffered -i “error” | tee errors.txt

a screenshot of a terminal window showing a few lines of text .

与 Shell 脚本的集成(使用 grep 结合条件语句和循环)

在 shell 脚本中使用 grep 实现自动化的示例

(本节内容更复杂,需要在 Linux 上配置更多的虚拟机和 Windows。没有时间分享示例,我建议将 H2 更改为“Using grep with conditional statements and loops”)

在下面的示例中,我们使用 grep -i 搜索特定模式,并将输出通过管道传递给 while 循环,随后处理每一行匹配的结果。

#!/bin/bash

LOG_FILE=”/var/log/syslog”

PATTERN=”authentication”

grep -i “$PATTERN” “$LOG_FILE” | while read -r line; do

echo “Processing line: $line”

# 在此处执行额外处理

完成

a screenshot of a command line window with a lot of text on it .

在下面的示例中,我们使用带有 ps 和 grep 命令的条件语句来检查服务是正在运行还是未运行。

#!/bin/bash

SERVICE=”CUPS”

if ! ps aux | grep -v grep | grep -q “$SERVICE”; then

echo ” $SERVICE is not running!”

else

echo “$SERVICE is running.”

fi

a black screen with a bunch of text on it .

故障排查与常见误区

解决编码问题

编码不匹配可能会导致在搜索不同编码字符中的模式时,grep 命令失败。我们可以设置区域设置(LC_ALL=C),或使用 –encoding 选项来纠正编码问题。

处理特殊字符与转义

正则表达式使用需要进行转义的特殊字符,才能按字面含义使用。反斜杠(\)用于转义这些字符;或者可以使用 -F(固定字符串)选项,将模式当作字面字符串处理。

调试复杂的正则表达式模式

当复杂的正则表达式未能按预期场景返回结果时,有时会很难排查。将其拆分成小部分,逐个测试,然后再组合起来,可以节省时间并帮助你定位问题。

结论

我们已经全面介绍了 grep 命令,从基础功能到诸如正则表达式这样的进阶技巧、grep 命令的不同选项、将 grep 与其他命令进行管道连接、重定向输出、脚本编写以及排错技巧。就像任何其他 PowerShell 技巧一样,通过亲自动手实践并对 grep 命令进行尝试,可以提高理解力,并帮助你发掘掌握系统自动化的隐藏可能性。



分享到

了解更多

关于作者

Tyler reese

Tyler Reese

产品管理副总裁,CISSP

凭借在软件安全行业超过二十年的经验,Tyler Reese 对当今企业面临的快速演变的身份与安全挑战非常熟悉。目前,他担任 Netwrix Identity and Access Management 组合的产品总监;他的职责包括评估市场趋势、确定 IAM 产品线的发展方向,并最终满足终端用户的需求。他的职业经历从为财富 500 强公司提供 IAM 咨询,到在一家大型直销面向消费者(direct-to-consumer)的公司担任企业架构师,涵盖范围十分广泛。 目前,他持有 CISSP 认证。