天天看點

Shell正規表達式 & Grep正規表達式 & shell字元串處理

摘自:http://hi.baidu.com/door17/blog/item/7a049a396b6ed7f23b87ce2c.html

http://blog.csdn.net/myvilla/archive/2006/08/31/1150598.aspx

Shell正規表達式

一個正規表達式就是由普通字元(例如字元 a 到 z)以及特殊字元(稱為元字元)組成的文字模式。該模式描述在查找文字主體時待比對的一個或多個字元串。正規表達式作為一個模闆,将某個字元模式與所搜尋的字元串進行比對。

/ hmcLinux聯盟

将下一個字元标記為一個特殊字元、或一個原義字元、或一個 後向引用、或一個八進制轉義符。例如,'n' 比對字元 "n"。'/n' 比對一個換行符。序列 '//' 比對 "/" 而 "/(" 則比對 "("。

^ hmcLinux聯盟

比對輸入字元串的開始位置。

$ hmcLinux聯盟

比對輸入字元串的結束位置。

* hmcLinux聯盟

比對前面的子表達式零次或多次。例如,zo* 能比對 "z" 以及 "zoo"。 * 等價于{0,}。

+ hmcLinux聯盟

比對前面的子表達式一次或多次。例如,'zo+' 能比對 "zo" 以及 "zoo",但不能比對 "z"。+ 等價于 {1,}。

? hmcLinux聯盟

比對前面的子表達式零次或一次。例如,"do(es)?" 可以比對 "do" 或 "does" 中的"do" 。? 等價于 {0,1}。

{n} hmcLinux聯盟

n 是一個非負整數。比對确定的 n 次。例如,'o{2}' 不能比對 "Bob" 中的 'o',但是能比對 "food" 中的兩個 o。

{n,} hmcLinux聯盟

n 是一個非負整數。至少比對n 次。例如,'o{2,}' 不能比對 "Bob" 中的 'o',但能比對 "foooood" 中的所有 o。'o{1,}' 等價于 'o+'。'o{0,}' 則等價于 'o*'。

{n,m} hmcLinux聯盟

m 和 n 均為非負整數,其中n <= m。最少比對 n 次且最多比對 m 次。 "o{1,3}" 将比對 "fooooood" 中的前三個 o。'o{0,1}' 等價于 'o?'。請注意在逗号和兩個數之間不能有空格。

? hmcLinux聯盟

當該字元緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 後面時,比對模式是非貪婪的。非貪婪模式盡可能少的比對所搜尋的字元串,而預設的貪婪模式則盡可能多的比對所搜尋的字元串。例如,對于字元串 "oooo",'o+?' 将比對單個 "o",而 'o+' 将比對所有 'o'。

. hmcLinux聯盟

比對除 "/n" 之外的任何單個字元。要比對包括 '/n' 在内的任何字元,請使用象 '[./n]' 的模式。

(pattern) hmcLinux聯盟

比對pattern 并擷取這一比對。所擷取的比對可以從産生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在Visual Basic Scripting Edition 中則使用 $0…$9 屬性。要比對圓括号字元,請使用 '/(' 或 '/)'。

(?:pattern) hmcLinux聯盟

比對 pattern 但不擷取比對結果,也就是說這是一個非擷取比對,不進行存儲供以後使用。這在使用 "或" 字元 (|) 來組合一個模式的各個部分是很有用。例如, 'industr(?:y|ies) 就是一個比 'industry|industries' 更簡略的表達式。

(?=pattern) hmcLinux聯盟

正向預查,在任何比對 pattern 的字元串開始處比對查找字元串。這是一個非擷取比對,也就是說,該比對不需要擷取供以後使用。例如, 'Windows (?=95|98|NT|2000)' 能比對 "Windows 2000" 中的 "Windows" ,但不能比對 "Windows 3.1" 中的 "Windows"。預查不消耗字元,也就是說,在一個比對發生後,在最後一次比對之後立即開始下一次比對的搜尋,而不是從包含預查的字元之後開始。

(?!pattern) hmcLinux聯盟

負向預查,在任何不比對Negative lookahead matches the search string at any point where a string not matching pattern 的字元串開始處比對查找字元串。這是一個非擷取比對,也就是說,該比對不需要擷取供以後使用。例如'Windows (?!95|98|NT|2000)' 能比對 "Windows 3.1" 中的 "Windows",但不能比對 "Windows 2000" 中的 "Windows"。預查不消耗字元,也就是說,在一個比對發生後,在最後一次比對之後立即開始下一次比對的搜尋,而不是從包含預查的字元之後開始。

x|y hmcLinux聯盟

比對 x 或 y。例如,'z|food' 能比對 "z" 或 "food"。'(z|f)ood' 則比對 "zood" 或 "food"。

[xyz] hmcLinux聯盟

字元集合。比對所包含的任意一個字元。例如, '[abc]' 可以比對 "plain" 中的 'a'。

[^xyz] hmcLinux聯盟

負值字元集合。比對未包含的任意字元。例如, '[^abc]' 可以比對 "plain" 中的'p'。

[a-z] hmcLinux聯盟

字元範圍。比對指定範圍内的任意字元。例如,'[a-z]' 可以比對 'a' 到 'z' 範圍内的任意小寫字母字元。

[^a-z] hmcLinux聯盟

負值字元範圍。比對任何不在指定範圍内的任意字元。例如,'[^a-z]' 可以比對任何不在 'a' 到 'z' 範圍内的任意字元。

/b hmcLinux聯盟

比對一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er/b' 可以比對"never" 中的 'er',但不能比對 "verb" 中的 'er'。

/B hmcLinux聯盟

比對非單詞邊界。'er/B' 能比對 "verb" 中的 'er',但不能比對 "never" 中的 'er'。

/cx hmcLinux聯盟

比對由x指明的控制字元。例如, /cM 比對一個 Control-M 或回車符。 x 的值必須為 A-Z 或 a-z 之一。否則,将 c 視為一個原義的 'c' 字元。

/d hmcLinux聯盟

比對一個數字字元。等價于 [0-9]。

/D hmcLinux聯盟

比對一個非數字字元。等價于 [^0-9]。

/f hmcLinux聯盟

比對一個換頁符。等價于 /x0c 和 /cL。

/n hmcLinux聯盟

比對一個換行符。等價于 /x0a 和 /cJ。

/r hmcLinux聯盟

比對一個回車符。等價于 /x0d 和 /cM。

/s hmcLinux聯盟

比對任何空白字元,包括空格、制表符、換頁符等等。等價于 [ /f/n/r/t/v]。

/S hmcLinux聯盟

比對任何非空白字元。等價于 [^ /f/n/r/t/v]。

/t hmcLinux聯盟

比對一個制表符。等價于 /x09 和 /cI。

/v hmcLinux聯盟

比對一個垂直制表符。等價于 /x0b 和 /cK。

/w hmcLinux聯盟

比對包括下劃線的任何單詞字元。等價于'[A-Za-z0-9_]'。

/W hmcLinux聯盟

比對任何非單詞字元。等價于 '[^A-Za-z0-9_]'。

/xn hmcLinux聯盟

比對 n,其中 n 為十六進制轉義值。十六進制轉義值必須為确定的兩個數字長。例如, '/x41' 比對 "A"。'/x041' 則等價于 '/x04' & "1"。正規表達式中可以使用 ASCII 編碼。.

/num hmcLinux聯盟

比對 num,其中 num 是一個正整數。對所擷取的比對的引用。例如,'(.)/1' 比對兩個連續的相同字元。

/n hmcLinux聯盟

辨別一個八進制轉義值或一個後向引用。如果 /n 之前至少 n 個擷取的子表達式,則 n 為後向引用。否則,如果 n 為八進制數字 (0-7),則 n 為一個八進制轉義值。

/nm hmcLinux聯盟

辨別一個八進制轉義值或一個後向引用。如果 /nm 之前至少有is preceded by at least nm 個擷取得子表達式,則 nm 為後向引用。如果 /nm 之前至少有 n 個擷取,則 n 為一個後跟文字 m 的後向引用。如果前面的條件都不滿足,若 n 和 m 均為八進制數字 (0-7),則 /nm 将比對八進制轉義值 nm。

/nml hmcLinux聯盟

如果 n 為八進制數字 (0-3),且 m 和 l 均為八進制數字 (0-7),則比對八進制轉義值 nml。

/un hmcLinux聯盟

比對 n,其中 n 是一個用四個十六進制數字表示的 Unicode 字元。例如, /u00A9 比對版權符号 (?)。

Grep正規表達式

要用好grep這個工具,其實就是要寫好正規表達式,是以這裡不對grep的所有功能進行執行個體講解,隻列幾個例子,講解一個正規表達式的寫法。

$ ls -l | grep '^a'

通過管道過濾ls -l輸出的内容,隻顯示以a開頭的行。

$ grep 'test' d*

顯示所有以d開頭的檔案中包含test的行。

$ grep 'test' aa bb cc

顯示在aa,bb,cc檔案中比對test的行。

$ grep '[a-z]/{5/}' aa

顯示所有包含每個字元串至少有5個連續小寫字元的字元串的行。

$ grep 'w/(es/)t.*/1' aa

如果west被比對,則es就被存儲到記憶體中,并标記為1,然後搜尋任意個字元(.*),這些字元後面緊跟着另外一個es(/1),找到就顯示該行。如果用egrep或grep -E,就不用"/"号進行轉義,直接寫成'w(es)t.*/1'就可以了。

grep正規表達式元字元集(基本集)

^

錨定行的開始 如:'^grep'比對所有以grep開頭的行。

$

錨定行的結束 如:'grep$'比對所有以grep結尾的行。

.

比對一個非換行符的字元 如:'gr.p'比對gr後接一個任意字元,然後是p。

*

比對零個或多個先前字元 如:'*grep'比對所有一個或多個空格後緊跟grep的行。 .*一起用代表任意字元。

[]

比對一個指定範圍内的字元,如'[Gg]rep'比對Grep和grep。

[^]

比對一個不在指定範圍内的字元,如:'[^A-FH-Z]rep'比對不包含A-R和T-Z的一個字母開頭,緊跟rep的行。

/(../)

标記比對字元,如'/(love/)',love被标記為1。

/<

錨定單詞的開始,如:'/

/>

錨定單詞的結束,如'grep/>'比對包含以grep結尾的單詞的行。

x/{m/}

重複字元x,m次,如:'0/{5/}'比對包含5個o的行。

x/{m,/}

重複字元x,至少m次,如:'o/{5,/}'比對至少有5個o的行。

x/{m,n/}

重複字元x,至少m次,不多于n次,如:'o/{5,10/}'比對5--10個o的行。

/w

比對文字和數字字元,也就是[A-Za-z0-9],如:'G/w*p'比對以G後跟零個或多個文字或數字字元,然後是p。

/W

/w的反置形式,比對一個或多個非單詞字元,如點号句号等。

/b

單詞鎖定符,如: '/bgrepb/'隻比對grep。 

Shell字元串處理

  1. 構造字元串

    直接構造

    STR_ZERO=hello

    STR_FIRST="i am a string"

    STR_SECOND='success'

    重複多次

    #repeat the first parm($1) by $2 times

    strRepeat()

    {

    local x=$2

    if [ "$x" == "" ]; then

    x=0

    fi

    local STR_TEMP=""

    while [ $x -ge 1 ];

    do

    STR_TEMP=`printf "%s%s" "$STR_TEMP" "$1"`

    x=`expr $x - 1`

    done

    echo $STR_TEMP

    }

    舉例:

    STR_REPEAT=`strRepeat "$USER_NAME" 3`

    echo "repeat = $STR_REPEAT"

  2. 指派與拷貝

    直接指派

    與構造字元串一樣

    USER_NAME=terry

    從變量指派

    ALIASE_NAME=$USER_NAME

  3. 聯接

    直接聯接兩個字元串

    STR_TEMP=`printf "%s%s" "$STR_ZERO" "$USER_NAME"`

    使用printf可以進行更複雜的聯接

  4. 求長

    求字元數(char)

    COUNT_CHAR=`echo "$STR_FIRST" | wc -m`

    echo $COUNT_CHAR

    求位元組數(byte)

    COUNT_BYTE=`echo "$STR_FIRST" | wc -c`

    echo $COUNT_BYTE

    求字數(word)

    COUNT_WORD=`echo "$STR_FIRST" | wc -w`

    echo $COUNT_WORD

  5. 比較

    相等比較

    str1 = str2

    不等比較

    str1 != str2

    舉例:

    if [ "$USER_NAME" = "terry" ]; then

    echo "I am terry"

    fi

    小于比較

    # return 0 if the two string is equal, return 1 if $1 < $2, else 2 strCompare() { local x=0 if [ "$1" != "$2" ]; then x=2 local TEMP=`printf "%s/n%s" "$1" "$2"` local TEMP2=`(echo "$1"; echo "$2") | sort` if [ "$TEMP" = "$TEMP2" ]; then x=1 fi fi echo $x }

  6. 測試

    判空

    -z str

    判非空

    -n str

    是否為數字

    # return 0 if the string is num, otherwise 1

    strIsNum()

    {

    local RET=1

    if [ -n "$1" ]; then

    local STR_TEMP=`echo "$1" | sed 's/[0-9]//g'`

    if [ -z "$STR_TEMP" ]; then

    RET=0

    fi

    fi

    echo $RET

    }

    舉例:

    if [ -n "$USER_NAME" ]; then

    echo "my name is NOT empty"

    fi

    echo `strIsNum "9980"`

  7. 分割

    以符号+為準,将字元分割為左右兩部分

    使用sed

    舉例:

    指令 date --rfc-3339 seconds 的輸出為

    2007-04-14 15:09:47+08:00

    取其+左邊的部分

    date --rfc-3339 seconds | sed 's/+[0-9][0-9]:[0-9][0-9]//g'

    輸出為

    2007-04-14 15:09:47

    取+右邊的部分

    date --rfc-3339 seconds | sed 's/.*+//g'

    輸出為

    08:00

    以空格為分割符的字元串分割

    使用awk

    舉例:

    STR_FRUIT="Banana 0.89 100"

    取第3字段

    echo $STR_FRUIT | awk '{ print $3; }'

  8. 子字元串

    字元串1是否為字元串2的子字元串

    # return 0 is $1 is substring of $2, otherwise 1

    strIsSubstring()

    {

    local x=1

    case "$2" in

    *$1*) x=0;;

    esac

    echo $x

    }