介紹
grep
命令是 Linux 終端環境中最實用的命令之一。 grep
的名稱代表「全局正則表達式打印」。這意味著您可以使用 grep
檢查接收到的輸入是否與指定的模式匹配。這個看似微不足道的程序非常強大;它根據複雜的規則對輸入進行排序的能力使它成為許多命令鏈中的熱門連結。
在本教程中,您將探索 grep
命令的選項,然後深入使用正則表達式進行更高級的搜索。
先決條件
要按照本指南進行操作,您需要能夠訪問運行基於 Linux 的操作系統的計算機。這可以是您通過 SSH 連接的虛擬私有服務器,也可以是您的本地計算機。請注意,此教程是在運行 Ubuntu 20.04 的 Linux 服務器上驗證的,但給出的示例應該適用於運行任何 Linux 發行版的任何版本的計算機。
如果您計劃使用遠程伺服器來按照這個指南操作,我們建議您先完成我們的初始伺服器設置指南。這樣做將為您建立一個安全的伺服器環境 — 包括一個具有sudo權限的非root用戶以及配置了UFW防火牆 — 您可以用來提升您的Linux技能。
基本用法
在本教程中,您將使用grep
來搜索GNU通用公共许可证第3版中的各種單詞和短語。
如果您使用的是Ubuntu系統,您可以在/usr/share/common-licenses
文件夾中找到該文件。將它複製到您的主目錄:
如果您使用的是其他系統,請使用curl
命令下載一份副本:
在本教程中,您還將使用BSD許可證文件。在Linux上,您可以使用以下命令將其複製到您的主目錄:
如果您使用的是其他系統,請使用以下命令創建文件:
現在您已經有了這些文件,您可以開始使用grep
進行工作。
在最基本的形式中,您使用grep
來匹配文本文件中的文字模式。這意味著如果您傳遞一個要搜索的詞給grep
,它將打印出文件中包含該詞的每一行。
執行以下命令使用grep
來搜索包含單詞GNU
的每一行:
第一個參數GNU
是你要搜索的模式,而第二個參數GPL-3
是你希望搜索的輸入文件。
結果輸出將是包含模式文字的每一行:
Output GNU GENERAL PUBLIC LICENSE
The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
Developers that use the GNU GPL protect your rights with two steps:
"This License" refers to version 3 of the GNU General Public License.
13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...
在某些系統上,你搜索的模式將會在輸出中被突出顯示。
常見選項
默認情況下,grep
將在輸入文件中搜索指定的精確模式並返回找到的行。不過,你可以通過向grep
添加一些可選標誌來使這種行為更有用。
如果你想讓grep
忽略搜索參數的“大小寫”,並搜索大寫和小寫變化,你可以指定-i
或--ignore-case
選項。
在與之前相同的文件中搜索單詞license
的每個實例(包括大寫、小寫或混合大小寫)的命令如下:
結果包含:LICENSE
、license
和License
:
Output GNU GENERAL PUBLIC LICENSE
of this license document, but changing it is not allowed.
The GNU General Public License is a free, copyleft license for
The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price. Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
"This License" refers to version 3 of the GNU General Public License.
"The Program" refers to any copyrightable work licensed under this
...
...
如果有一個帶有LiCeNsE
的實例,那也將被返回。
如果您想找到所有不包含特定模式的行,您可以使用-v
或--invert-match
选项。
使用以下命令在BSD许可证中搜索不包含单词the
的每一行:
您将收到以下输出:
OutputAll rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...
由于您没有指定“忽略大小写”选项,因此最后两个项被返回为不包含单词the
。
知道匹配发生在哪一行通常是有用的。您可以通过使用-n
或--line-number
选项来实现这一点。使用此标志重新运行上一个示例:
这将返回以下文本:
Output2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13: may be used to endorse or promote products derived from this software
14: without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...
现在,如果您想要对每一行不包含the
的行进行更改,您可以引用行号。在处理源代码时,这特别方便。
正则表达式
在介绍中,您了解到grep
代表“全局正则表达式打印”。 “正则表达式”是描述特定搜索模式的文本字符串。
不同的应用程序和编程语言以略有不同的方式实现正则表达式。在本教程中,您将只探索grep
描述其模式的一小部分方式。
字面匹配
在本教程中的先前示例中,當您搜索單詞GNU
和the
時,實際上是在搜索基本正則表達式,這些表達式匹配了精確的字符串GNU
和the
。精確指定要匹配的字符的模式稱為“字面量”,因為它們按字面意義匹配模式,即逐個字符地。
將這些視為匹配一串字符而不是匹配單詞是有幫助的。隨著您學習更複雜的模式,這將成為一個更重要的區別。
所有字母和數字字符(以及某些其他字符)都會按字面意義進行匹配,除非受到其他表達機制的修改。
錨點匹配
錨點是指定匹配必須發生在行中的哪個位置才能有效的特殊字符。
例如,使用錨點,您可以指定您只想要匹配位於行的開頭的GNU
的行。為此,您可以在字面串之前使用^
錨點。
運行以下命令來搜索GPL-3
文件,找到以GNU
開頭的行:
這個命令將返回以下兩行:
OutputGNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published
同樣地,你可以使用$
錨點在模式的末尾,表示匹配只在行的最末出現才有效。
這個命令將匹配在GPL-3
文件中以單詞and
結尾的每一行:
你將收到這個輸出:
Outputthat there is no warranty for this free software. For both users' and
The precise terms and conditions for copying, distribution and
License. Each licensee is addressed as "you". "Licensees" and
receive it, in any medium, provided that you conspicuously and
alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and
匹配任何字符
句點字符(.)在正則表達式中用於表示指定位置可以存在任何單個字符。
例如,要匹配GPL-3
文件中的任何兩個字符,然後是字符串cept
,你可以使用以下模式:
這個命令返回以下輸出:
Outputuse, which is precisely where it is most unacceptable. Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
You may not propagate or modify a covered work except as expressly
9. Acceptance Not Required for Having Copies.
...
...
這個輸出包含了accept
和except
以及這兩個詞的變體。該模式也會匹配z2cept
如果找到的話。
括號表達式
通過將一組字符放在括號中(\[
和 \]
),您可以指定該位置的字符可以是括號組中找到的任何一個字符。
例如,要查找包含too
或two
的行,您可以通過以下模式簡潔地指定這些變化:
輸出顯示文件中存在這兩種變體:
Outputyour programs, too.
freedoms that you received. You must make sure that they, too, receive
Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
Corresponding Source from a network server at no charge.
...
...
括號表示法為您提供了一些有趣的選擇。您可以通過在括號內的字符列表開頭使用^
字符來使模式與括號內的字符之外的任何字符匹配。
此示例類似於模式.ode
,但不會匹配模式code
:
這是您將收到的輸出:
Output 1. Source Code.
model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:
請注意,在第二行返回的內容中,實際上存在單詞code
。這不是正則表達式或grep的失敗。相反,此行之所以返回,是因為在該行之前找到了模式mode
,該模式在單詞model
中找到。該行被返回是因為有一個與模式匹配的實例。
括號的另一個有用功能是,您可以指定一系列字符,而不是逐個輸入每個可用的字符。
這意味著如果您想查找每一行開頭是大寫字母的話,您可以使用以下模式:
這是此表達式返回的輸出:
OutputGNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License. Each licensee is addressed as "you". "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
...
由於一些遺留的排序問題,通常更準確的做法是使用 POSIX 字符類,而不是像您剛才使用的字符範圍。
討論每個 POSIX 字符類超出了本指南的範圍,但一個示例可以完成與先前示例相同的過程,它使用括號選擇器內的\[:upper:\]
字符類:
輸出將與以前相同。
重複模式零次或更多次
最後,最常用的元字符之一是星號,或*
,表示“重複前一個字符或表達式零次或更多次”。
要查找GPL-3
文件中每一行,該行包含開放和閉合括號,之間只有字母和單個空格,請使用以下表達式:
您將得到以下輸出:
Output Copyright (C) 2007 Free Software Foundation, Inc.
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
(including a physical distribution medium), accompanied by the
(including a physical distribution medium), accompanied by a
place (gratis or for a charge), and offer equivalent access to the
...
...
到目前為止,您已在表達式中使用了句點、星號和其他字符,但有時您需要專門搜索這些字符。
轉義元字符
有時候,您需要搜尋文字中的字面句號或字面開括號,尤其在處理原始碼或配置文件時。因為這些字符在正則表達式中具有特殊含義,您需要“逃避”這些字符,以告訴 grep
在這種情況下不希望使用它們的特殊含義。
您可以通過在通常具有特殊含義的字符前面使用反斜杠字符(\
)來進行字符逃避。
例如,要查找任何以大寫字母開頭且以句號結尾的行,請使用以下表達式來逃避結尾的句號,以便它表示字面句號而不是通常的“任何字符”含義:
這是您將看到的輸出:
OutputSource.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.
現在讓我們看看其他正則表達式選項。
擴展正則表達式
grep
命令支持使用 -E
標誌或調用 egrep
命令而不是 grep
來使用更廣泛的正則表達式語言。
這些選項打開了“擴展正則表達式”的功能。擴展正則表達式包括所有基本的元字符,以及其他元字符來表示更複雜的匹配。
分組
擴展正則表達式最有用的能力之一是將表達式分組在一起,以便作為一個單位進行操作或引用。
要將表達式分組在一起,請將它們放在括號中。如果您想在不使用擴展正則表達式的情況下使用括號,可以使用反斜杠將其逃避,以啟用此功能。這意味著以下三個表達式在功能上是等效的:
交替
與方括號表達式可以指定單個字符匹配的不同可能選擇類似,交替允許您為字符串或表達式集指定替代匹配。
要指示交替,請使用管道字符 |
。這些通常在括號分組中使用,以指定其中一個或兩個以上可能性應該被視為匹配。
以下將在文本中查找 GPL
或 通用公共許可證
:
輸出如下:
Output The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price. Our General Public Licenses are designed to make sure that you
Developers that use the GNU GPL protect your rights with two steps:
For the developers' and authors' protection, the GPL clearly explains
authors' sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
...
交替可以通過在選擇組內添加額外的選項並用額外的管道 (|
) 字符分隔來在兩個以上的選擇之間進行選擇。
量詞
像 *
元字符一樣,它可以與前一個字符或字符集匹配零次或更多次,擴展正則表達式中還有其他可用的元字符,指定發生的次數。
要匹配一個字符零次或一次,您可以使用 ?
字符。這使得之前的字符或字符集成為可選的。
下面的示例將 copy
放在一個可選的組中,從而匹配 copyright
和 right
:
您將收到以下輸出:
Output Copyright (C) 2007 Free Software Foundation, Inc.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
"Copyright" also means copyright-like laws that apply to other kinds of
...
+
字符會一次或多次匹配一個表達式。這幾乎與 *
元字符相似,但是使用 +
字符時,表達式必須至少匹配一次。
以下表達式匹配字符串 free
和一個或多個非空白字符:
您將看到以下輸出:
Output The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for
you modify it: responsibilities to respect the freedom of others.
freedomss that you received. You must make sure that they, too, receive
protecting users' freedom to change the software. The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.
指定匹配重複
為了指定匹配重複的次數,請使用大括號字符({
和 }
)。這些字符讓您可以指定一個確切的數量、一個範圍,或是表達式可以匹配的次數的上限或下限。
使用以下表達式來查找GPL-3
文件中包含三個元音字母的所有行:
返回的每一行都有一個包含三個元音字母的單詞:
Outputchanged, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this
為了匹配任何具有16到20個字符之間的單詞,請使用以下表達式:
這是該命令的輸出:
Output certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
c) Prohibiting misrepresentation of the origin of that material, or
僅顯示包含該長度內的單詞的行。
結論
grep
在查找文件或文件系統層次結構中的模式時很有用,所以花點時間熟悉它的選項和語法是值得的。
正則表達式更加靈活,可以與許多常用程序一起使用。例如,許多文本編輯器實現了用於搜索和替換文本的正則表達式。
此外,大多數現代編程語言使用正則表達式對特定數據進行操作。一旦您理解了正則表達式,就能將這些知識應用於許多常見的與計算機相關的任務中,從在文本編輯器中進行高級搜索到驗證用戶輸入。