天天看點

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

當我們在 unix/linux 下使用特定的指令從字元串或檔案中讀取或編輯文本時,我們經常需要過濾輸出以得到感興趣的部分。這時正規表達式就派上用場了。

<a target="_blank"></a>

正規表達式可以定義為代表若幹個字元序列的字元串。它最重要的功能之一就是它允許你過濾一條指令或一個檔案的輸出、編輯文本或配置檔案的一部分等等。

正規表達式由以下内容組合而成:

普通字元,例如空格、下劃線、a-z、a-z、0-9。

可以擴充為普通字元的元字元,它們包括:

<code>(.)</code> 它比對除了換行符外的任何單個字元。

<code>(*)</code> 它比對零個或多個在其之前緊挨着的字元。

<code>[ character(s) ]</code> 它比對任何由其中的字元/字元集指定的字元,你可以使用連字元(-)代表字元區間,例如 [a-f]、[1-5]等。

<code>^</code> 它比對檔案中一行的開頭。

<code>$</code> 它比對檔案中一行的結尾。

<code>\</code> 這是一個轉義字元。

你必須使用類似 awk 這樣的文本過濾工具來過濾文本。你還可以把 awk 自身當作一個程式設計語言。但由于這個指南的适用範圍是關于使用 awk 的,我會按照一個簡單的指令行過濾工具來介紹它。

awk 的一般文法如下:

<code># awk 'script' filename</code>

此處 <code>'script'</code> 是一個由 awk 可以了解并應用于 filename 的指令集合。

它通過讀取檔案中的給定行,複制該行的内容并在該行上執行腳本的方式工作。這個過程會在該檔案中的所有行上重複。

該腳本 <code>'script'</code> 中内容的格式是 <code>'/pattern/ action'</code>,其中 <code>pattern</code> 是一個正規表達式,而<code>action</code> 是當 awk 在該行中找到此模式時應當執行的動作。

在下面的例子中,我們将聚焦于之前讨論過的元字元。

下面的例子列印檔案 /etc/hosts 中的所有行,因為沒有指定任何的模式。

<code># awk '//{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

awk 列印檔案中的所有行

在下面的示例中,指定了模式 <code>localhost</code>,是以 awk 将比對檔案 <code>/etc/hosts</code> 中有 <code>localhost</code> 的那些行。

<code># awk '/localhost/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

awk 列印檔案中比對模式的行

在下面的例子中,符号 <code>(.)</code> 将比對包含 loc、localhost、localnet 的字元串。

這裡的正規表達式的意思是比對 l一個字元c。

<code># awk '/l.c/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 列印檔案中比對模式的字元串

(lctt 譯者注:此處原文作者了解有誤,感謝微信讀者“止此而已”的提醒,<code>*</code> 在此處表示其前一個字元重複零次或多次,是以實際上相當于 <code>*</code> 及前面的字元是無用的。)

在下面的例子中,将比對包含 localhost、localnet、lines, capable 的字元串。将比對帶有 <code>c</code> 字元的字元串。

<code># awk '/l*c/{print}' /etc/localhost</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 比對檔案中的字元串

你可能也意識到 <code>(*)</code> 将會嘗試比對它可能檢測到的最長的比對。

讓我們看一看可以證明這一點的例子,正規表達式 <code>t*t</code> 的意思是在下面的行中比對以 <code>t</code> 開始和 <code>t</code> 結束的字元串:将比對帶有 t 字元的字元串:

<code>this is tecmint, where you get the best good tutorials, how to's, guides, tecmint.</code>

當你使用模式 <code>/t*t/</code> 時,會得到如下可能的結果:以下字元串隻是有 t 字元而已:

<code>this is t</code>

<code>this is tecmint</code>

<code>this is tecmint, where you get t</code>

<code>this is tecmint, where you get the best good t</code>

<code>this is tecmint, where you get the best good tutorials, how t</code>

<code>this is tecmint, where you get the best good tutorials, how tos, guides, t</code>

<code>this is tecmint, where you get the best good tutorials, how tos, guides, tecmint</code>

在 <code>/t*t/</code> 中的通配符 <code>(*)</code> 将使得 awk 選擇比對的最後一項:以下字元串隻是有 t 字元而已:

<code>this is tecmint, where you get the best good tutorials, how to's, guides, tecmint</code>

以集合 [al1] 為例,awk 将比對檔案 /etc/hosts 中所有包含字元 a 或 l 或 1 的字元串。

<code># awk '/[al1]/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 列印檔案中比對的字元

下一個例子比對以 <code>k</code> 或 <code>k</code> 開始(非指行首是該字母),後面跟着一個 <code>t</code> 的字元串:

<code># awk '/[kk]t/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

awk 所能了解的字元:

<code>[0-9]</code> 代表一個單獨的數字

<code>[a-z]</code> 代表一個單獨的小寫字母

<code>[a-z]</code> 代表一個單獨的大寫字母

<code>[a-za-z]</code> 代表一個單獨的字母

<code>[a-za-z 0-9]</code> 代表一個單獨的字母或數字

讓我們看看下面的例子:

<code># awk '/[0-9]/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 列印檔案中比對的數字

在上面的例子中,檔案 /etc/hosts 中的所有行都至少包含一個單獨的數字 [0-9]。

在下面的例子中,它比對所有以給定模式開頭的行:

<code># awk '/^fe/{print}' /etc/hosts</code>

<code># awk '/^ff/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 列印與模式比對的行

它将比對所有以給定模式結尾的行:

<code># awk '/ab$/{print}' /etc/hosts</code>

<code># awk '/ost$/{print}' /etc/hosts</code>

<code># awk '/rs$/{print}' /etc/hosts</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

使用 awk 列印與模式比對的字元串

它允許你将該轉義字元後面的字元作為文字,即了解為其字面的意思。

在下面的例子中,第一個指令列印出檔案中的所有行,第二個指令中我想比對具有 $25.00 的一行,但我并未使用轉義字元,因而沒有列印出任何内容。

第三個指令是正确的,因為一個這裡使用了一個轉義字元以轉義 $,以将其識别為 '$'(而非元字元)。

<code># awk '//{print}' deals.txt</code>

<code># awk '/$25.00/{print}' deals.txt</code>

<code># awk '/\$25.00/{print}' deals.txt</code>

awk 系列:如何使用 awk 和正規表達式過濾文本或檔案中的字元串

結合轉義字元使用 awk

以上内容并不是 awk 指令用做過濾工具的全部,上述的示例均是 awk 的基礎操作。

原文釋出時間為:2016-07-18

本文來自雲栖社群合作夥伴“linux中國”

繼續閱讀