Shell工具中正則表達式技術
awk, sed和egrep是Unix中文本處理相關的Shell工具。awk採用了DFA匹配引擎。egrep依據說使用的功能在DFA和NFA引擎之間進行切換(實現了兩中引擎)。sed採用傳統的NFA匹配引擎。如果想進一步瞭解傳統的NFA引擎背後的規則,請看“正則表達式和模式匹配”一節。
本章涵蓋GNU egrep 2.4.2,一個文本行搜索程序;GNU sed 3.2,一個腳本編輯命令工具;和GNU awk 3.1,一種文本處理語言。
支持的元字符
awk, sed和egrep支持表61到表65中列出來的元字符和元序列。關於每一個元字符的詳述,請看“正則表達式元字符、模式和結構”一節。
Shell字符表示 |
||
序列名 |
序列描述 |
支持工具 |
/a |
告警(bell) |
awk, sed |
/b |
空格,只有在字符類中有效 |
awk, |
/f |
分頁 |
awk, sed |
/n |
換行 |
awk, sed |
/r |
回車 |
awk, sed |
/t |
水平製表符 |
awk, sed |
/v |
垂直製表符 |
awk, sed |
/ooctal |
通過1、2或3個八進制碼數指定的字符 |
sed |
/octal |
通過1、2或3個八進制碼數指定的字符 |
awk |
/xhex |
通過1個或2個十六進制數指定的字符 |
awk, sed |
/x{hex} |
通過十六進制碼指定的字符 |
awk, sed |
/ddecimal |
通過1個或2個十進制數指定的字符 |
awk, sed |
/cchar |
命名的控制字符 |
sed |
/b |
空格 |
awk |
/matecharacter |
轉義元字符,所以它僅表示自身 |
awk, sed, egrep |
表61 Shell字符表示
Shell字符類和類似(class-like)結構 |
||
字符類 |
類描述 |
支持工具 |
[…] |
列出來的或包含在列表範圍的單一字符 |
awk, sed, egrep |
[^…] |
不在列出來的或不包含在列表範圍的單一字符 |
awk, sed, egrep |
. |
除換行之外的任意字符 |
awk, sed, egrep |
/w |
字字符,[a-zA-Z0-9_] |
egrep, sed |
/W |
非字字符, [^a-zA-Z0-9_] |
egrep, sed |
[:prop:] |
匹配POSIX字符集內的任意字符 |
awk, sed |
[^[:prop:]] |
匹配不在POSIX字符集內的任意字符 |
awk, sed |
表62 Shell字符類和類似(class-like)結構
Shell錨和其他0寬測試 |
||
序列名 |
序列描述 |
支持工具 |
^ |
匹配字符串的開頭,即時有內切的換行 |
awk, sed, egrep |
$ |
匹配字符串末尾,即時有內切的換行 |
awk, sed, egrep |
/< |
匹配字邊界的起始位置 |
egrep |
/> |
匹配字邊界的末尾 |
egrep |
表63 Shell錨和其他0寬測試
Shell註釋和模式轉換器 |
||
模式名 |
模式描述 |
支持工具 |
flag:i或I |
ASCII字符大小寫不敏感匹配 |
sed |
命令行選項:-i |
ASCII字符大小寫不敏感匹配 |
egrep |
set IGNORECASE爲非0(none-zero) |
Unicode字符大小寫不敏感匹配 |
awk |
表64 hell註釋和模式轉換器
Shell歸組、捕獲、條件和控制 |
||
序列 |
序列描述 |
支持工具 |
(PATTERN) |
歸組 |
awk |
(PATTERN/) |
組和捕獲字匹配,填寫/1,/2,...,/9 |
sed |
/n |
包含第n個被捕獲子匹配 |
sed |
...|... |
替換;匹配一個或其他 |
awk, sed, egrep |
貪婪計量器 |
||
* |
匹配0或多次 |
awk, sed, egrep |
+ |
匹配1次或多次 |
awk, sed, egrep |
? |
匹配1次或0次 |
awk, sed, egrep |
/{n/} |
匹配精確的n次 |
sed, egrep |
/{n,/} |
至少匹配n次 |
sed, egrep |
/{x,y/} |
至少匹配x次,最多y次 |
sed, egrep |
表65 Shell歸組、捕獲、條件和控制
egrep
grep [options] pattern files
grep在文件搜索pattern發生的位置,並打印出每一個匹配的行。
實例
grep實例 |
$ echo 'Spiderman Menaces City!' > dailybugle.txt $ egrep -i 'spider[- ]?man' dailybugle.txt Spiderman Menaces City! |
sed
sed '[address1][,address2]s/pattern/replacement/[flags]' files
sed -f script files
默認的情況下sed把替換應用於files中的每一行。每一個address既可以是一個行號,也可以是一個正則表達式。當在正則表達式中使用時,必須在雙方斜杆之內定義(/.../)。
如果指定了address1,那麼替換從指定的行開始,或者第一個匹配的行,到文件末尾爲止,或由address2指定或匹配的行。&和/n將在replacement中作爲匹配結果被解釋。
&被pattern匹配的文本替換。/n與當前匹配中捕獲組(1...9)有關。以下是可用的標識:
n 替換一行內第n個匹配,n在1到512之間。
g 替換一行中所發生的所有pattern。
p 打印所有成功替換的行。
w file 把成功的替換寫到文件中。
實例
把時間格式從MM/DD/YYYY 改爲DD.MM.YYYY |
$ echo 12/30/1969' | sed 's!/([0-9][0-9]/)//([0-9][0-9]/)//([0-9]/{2,4/}/)! /2./1./3!g' |
awk
awk 'instruction' files
awk –f script files
包含在instruction或 script中腳本必須由一系列的/pattern/ {action}對組成。action碼應用於被pattern的每一行。awk還爲模式匹配提供了一些函數。
函數
match(text, pattern)
如果pattern匹配text,返回text中匹配的起始位置。一個成功的匹配還設置變量RSTART的值爲匹配起始位置,設置變量RLENGTH的值爲匹配中字符的個數。
gsub(pattern, replacement, text)
用replacement來替換text中每一個pattern匹配,並返回替換的次數。如果沒有指定text則默認爲$0。
sub(pattern, replacement, text)
用replacement來替換text中第一個pattern匹配,並返回替換的次數。一個成功的替換返回1,一個不成功的替換返回0。如果沒有指定text則默認爲$0。
實例
創建一個awk文件,並通過命令行執行這個文件 |
$ cat sub.awk { gsub(/https?:////[a-z_.//w////#~:?+=&;%@!-]*/, "<a href=/"/&/">/&</a>"); } $ echo "Check the web site, http://www.oreilly.com/ catalog/repr" | awk -f sub.awk |