官术网_书友最值得收藏!

2.1 正則表達式與變量

2.1.1 正則表達式的組成與應用1.什么是正則表達式

正則表達式(Regular Expression,RE)就是由一系列特殊字符組成的字符串。其中每個特殊字符都被稱為元字符,這些元字符并不表示它們字面上的含義,而是被解釋為一些特定的含義。

正則表達式是由普通字符和元字符共同組成的集合,這個集合用來匹配(或指定)模式。正則表達式的主要功能是文本查詢和字符串操作,正則表達式可以匹配文本的一個字符或字符集合。

例如,a、b、1、2等字符屬于普通字符,普通字符可以按照字面意思理解,如a只能理解為英文的小寫字母a,沒有其他隱藏含義。而*、^、[ ]等元字符,shell賦予了它們超越字面意思的意義,如*符號的字面意義只是一個符號,而實際上卻表示了重復前面的字符0次或多次的隱藏含義。

2.正則表達式的組成

一個正則表達式包含下列一項或多項。

? 一個字符集:這里所指的字符集只包含普通字符,這些字符只表示它們的字面含義。正則表達式的最簡單形式就是只包含字符集,而不包含元字符。

? 錨:錨指定了正則表達式所要匹配的文本在文本行中所處的位置,如^和$就是錨。

? 修飾符:它們擴大或縮小(修改)了正則表達式匹配文本的范圍。修飾符包含星號、括號和反斜杠。

正則表達式中常用的一些符號以及對應的意義見表2-1。

表2-1 正則表達式中符號含義

其中:

? *用于匹配前面一個普通字符的0次或多次重復,例如,hel*o,*符號前面的普通字符是l,*字符就表示匹配l字符0次或多次,如字符串helo、hello、hellllllo都可以由hel*o來表示。

? .用于匹配任意一個字符,例如,…73. 表示前面3個字符為任意字符,第4和第5個字符是7和3,最后一個字符為任意字符,如xcb738、4J973U都能匹配上述字符串。

? ^用于匹配行首,表示行首的字符是^字符后面的那個字符,例如:^cloud表示匹配以cloud開頭的行

? $匹配行尾,$放在匹配字符之后,例如,micky$表示匹配以micky結尾的所有行,^$表示匹配空白行。

? []匹配字符集合,在正則表達式中,將匹配中括號字符集中的某一個字符,例如:

? [xyz]將會匹配字符x、y、或z。

? [c-n]匹配字符c~n之間的任意一個字符。

? [B-Pk-y]匹配從B~P,或者從k~y之間的任意一個字符。

? [a-z0-9]匹配任意小寫字母或數字。

? [^b-d]將會匹配范圍在b~d之外的任意一個字符。這就是使用^對字符集取反的一個實例。

? 將多個中括號字符集組合使用,能夠匹配一般的單詞或數字,例如,[Yy][Ee][Ss]能夠匹配yes、Yes、YES、yEs等,[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]可以匹配社保碼。

下面來看第1個例子,操作如下:

從輸出可以看出,精確匹配了exp2.txt文件中所有的非字符內容。

? \用來轉義某個特殊含義的字符,這意味著,這個特殊字符將會被解釋為字面含義。例如:

? \$將會被解釋成字符$,而不是RE中匹配行尾的特殊字符。相似的,\\將會被解釋為字符\。

? 轉義的尖括號\<...\>用于匹配單詞邊界,尖括號必須被轉義才含有特殊的含義,否則它就表示尖括號的字面含義。

? \<the\>完整匹配單詞the,不會匹配them、there、other等。

? \{\}系列符號表示前一個字符的重復次數。

? \{n\}匹配前面字符出現n次,如JO\{3\}B匹配JOOOB。

? \{n,\}匹配前面字符至少出現n次,如JO\{3,\}B匹配JOOOB、JOOOOB、JOOOOOB等字符串。

? \{n,m\}匹配前面字符出現n次與m次之間,如JO\{3,6\}B匹配JOOOB、JOOOOOOB等字符串。

例如,[a-z]\{5\}匹配5個小寫英文字母,如hello、house等。

繼續看第2個例子,操作如下:

可以看出,grep數字中精確匹配了iivey這個單詞。

2.1.2 shell中的變量與應用

1.變量的定義與分類

變量用于保存有用信息,如路徑名、文件名、數字等。Linux用戶使用變量定制其工作環境,使系統獲知用戶相關的配置。變量本質上是存儲數據的一個或多個計算機內存地址。

shell中的變量可分為如下幾種。

? 用戶自定義變量,如,myname,這類變量是由用戶自己定義、修改和使用。

? shell環境變量PATH,這類變量是由系統維護,用于設置用戶的shell工作環境,只有少數的變量用戶可以修改其值。

? 位置參數變量(Positional Parameters),這類變量通過命令行給程序傳遞執行參數,可用shift命令實現位置參數的遷移。

? 內部參數變量(Special Parameters),這類變量是Bash預定義的特殊變量,用戶不能修改其值。

2.變量的賦值

變量是某個值的名稱,引用變量值稱為變量替換,$符號是變量替換符號,如variable是變量名,那么$variable就表示變量的值。

變量賦值有兩種格式:

切記等號的兩邊不可以有空格;如果值(value)中包含空格,則必須用雙引號括起來,沒有空格時也可以用引號,效果和不用一樣;變量名只能包括大小寫字母(a~z和A~Z)、數字(0~9)、下畫線(_)等符號,并且變量名不能以數字開頭,否則視為無效變量名,變量區分大小寫。

3.變量聲明和使用

要使用變量,首先要進行變量的聲明,因為shell變量是弱類型的,因此不用聲明變量的類型,變量聲明與賦值的格式如下:

變量一旦聲明和賦值完成,就可以進行引用了,變量引用的方法有兩種:

兩種引用方法,在不同環境可進行不同選擇。一般規則是:如果變量名為一個字符時建議使用方式一,多于一個字符時建議使用方式二。例如,$a、${abc}。

要顯示變量,可以通過echo命令。echo命令可以顯示單個變量取值,變量名前加$即可,例如:

這里仍然建議,輸出引用變量時加{}。如果變量名多于一個字符,不加大括號可能會引起不必要的錯誤。

4.變量清除與只讀

當變量不再使用時,可以通過unset命令進行清除,unset命令清除變量的格式為:

有時想讓某個變量變成只讀,變量一旦設置為只讀,任何用戶不能對此變量進行重新賦值,此時可以使用readonly命令,設置變量只讀格式如下:

下面來看個例子:

可以看出,變量只讀后,無法清除和重新賦值。

5.內部參數變量

內部參數分兩類,一類是命令行參數相關的,見表2-2。

表2-2 內部參數變量與含義

這里有兩個變量需要注意:$*和$@都表示傳遞給腳本或函數的所有參數,但不被雙引號(" ")包含時,都以$1、$2、…、$n的形式輸出所有參數。但是當它們被雙引號("")包含時,$*會將所有的參數作為一個整體,以$1$2 … $n的形式輸出所有參數;而$@會將各個參數分開,以$1、$2、…、$n的形式輸出所有參數。

另一類內部參數是與進程狀態相關的,常見的參數見表2-3。

表2-3 與進程相關的內部參數與含義

下面看一個例子myscript1.sh,腳本內容如下:

這個例子集中演示了位置參數變量、內部參數變量的含義和輸出。執行腳本,后面跟上對應的參數,即可看到對應的不同變量的輸出。操作如下:

再來介紹一個IFS變量,shell腳本中有個變量叫IFS(Internal Field Seprator),內部域分隔符,IFS的默認值為空白(包括空格、Tab和新行),例如:

直接輸出IFS是看不到的,把IFS轉化為八進制就可以看到了,040是空格,011是Tab,012是換行符\n。最后一個012是因為echo默認是會換行的。

這里再來總結下$*和$@的區別,$*會根據IFS的不同來組合值,而$@則會將值用空格來組合值,推薦使用$@,而不是$*。

下面給出一個腳本myscript2.sh,通過輸出就能看到它們的差別:

執行上面腳本,輸出如下:

從這個腳本的執行結果,可以看出$@、$*以及與IFS的關系。

6.位置參數變量

位置參數是一種特殊的shell變量,用于從命令行向shell腳本傳遞參數。

$1表示第1個參數、$2表示第2個參數等,$0表示腳本的名字,從${10}開始,參數號需要用大括號括起來,如${10}、${11}、${100}等。那么位置參數主要用在什么地方呢?常用的環境有兩個:退出/返回從shell命令/腳本的命令行接受參數或在調用shell函數時為其傳遞參數。

7.退出/返回狀態

shell中有多種退出/返回狀態,在寫shell腳本的時候經常用到這些狀態,那么如何獲取腳本的退出/返回狀態呢?可以通過$?來實現。$?用來退出/返回上一條語句或腳本執行的狀態,常見狀態如下:

其實可以在shell腳本中設置退出/返回狀態,通過exit命令來實現。exit命令用于退出/返回腳本或當前shell,在退出/返回的時候,可以設置退出/返回狀態碼,方法如下:

其中,n是一個從0~255的整數,0表示成功退出/返回,非零表示遇到某種失敗,返回值被保存在狀態變量$?中。常見的退出/返回狀態碼見表2-4。

表2-4 常見的退出/返回狀態碼與含義

看下面幾個例子:

通過命令的執行和輸出,可以看出,每個退出/返回狀態碼的含義,明白了這些退出/返回狀態碼,就可以在寫shell的時候進行調用,以判斷命令是否執行成功。

8.命令替換

命令替換是指將命令的輸出作為命令替換位置的文本,命令替換的作用是抽取一個命令的輸出,然后使用=操作賦值到一個變量供以后使用。命令替換在shell編程中經常用到,有兩種使用格式,分別是:

注意是反引號,也就是鍵盤〈Esc〉下面的那個鍵,看下面的例子:

兩個例子都是將Nginx的進程數統計出來,然后賦給httpnum和httpnum1變量,在shell腳本中,變量這樣定義后,下面就可以直接引用了。兩種方式各有優缺點,推薦使用第2種方式。

9.read命令

read命令用來接收鍵盤輸入內容為變量賦值,具體用法如下:

若省略變量名,則會將輸入的內容存入默認REPLY變量中。看下面例子:

可以結合不同的引號為變量賦值,規則如下所述。

? 雙引號"":允許通過$符號引用其他變量值。

? 單引號'':禁止引用其他變量值,$視為普通字符,因此引用變量時不要用單引號。

? 反撇號``:將命令執行的結果輸出給變量。

看下面這個shell腳本myscript3.sh:

最后來執行腳本看看輸出結果:

2.1.3 變量測試、截取與替換

1.變量測試的用法

shell支持變量測試和默認賦值,當一個變量不存在的時候,可以默認給此變量進行賦值。變量測試和賦值有多種方式,常見的有4種情況,見表2-5。

表2-5 變量測試的幾種用法與含義

看下面這個操作過程,更能清晰地理解每個變量測試的含義:

2.字符串長度與截取

awk和sed可以進行文本中字符串的過濾、篩選和替換。其實,shell本身也支持這種功能,下面就來看看shell中字符串長度與截取的方法,見表2-6。

表2-6 字符串長度與截取的用法與含義

看下面這個例子,操作過程如下:

此外,shell還支持字符串替換,見表2-7。

表2-7 字符串替換用法

需要注意的是old中可以使用通配符。var可以是@或*,表示對每個位置參數進行替換,繼續看下面的例子,操作過程如下:

3.變量的間接引用

先來看一個例子:

這個例子中,想讓$str2輸出Hello World,那么echo $str2將輸出什么呢?是否能夠滿足要求?顯然不能,上面這個輸出中,最后echo $str2會輸出的值為str1,那么如何才能輸出所需要的值呢?可以這樣執行:

上面兩個命令都能實現將str1的值間接的賦給str2,最后結果為Hello World,滿足間接賦值要求。再來看個例子:

那么看下面這幾個組合輸出什么內容:

來執行看看結果:

很顯然,第2個是滿足需要的,通過間接引用變量,實現了變量值的替換。

4.同時輸出多行信息

同時輸出多行信息也經常會使用,有兩種方法可以實現,第1種是使用echo命令,用法如下:

注意,多行內容中不能出現雙引號,否則echo提前結束,若確實需要使用雙引號,需使用轉義字符\。同時輸出多行信息的第2個方法是使用here file,方法如下:

注意:END可以是任意字符串,只要上下一致即可,多行內容中不能出現內容為END開始的行,否則cat提前結束。

主站蜘蛛池模板: 修武县| 钟山县| 通化县| 平陆县| 开阳县| 潜江市| 普兰店市| 大荔县| 克什克腾旗| 高青县| 习水县| 曲靖市| 太康县| 黔南| 叙永县| 迭部县| 琼中| 南宫市| 富蕴县| 谢通门县| 龙江县| 红原县| 始兴县| 长乐市| 山东省| 平湖市| 辰溪县| 澳门| 盐池县| 新乡市| 新田县| 双江| 建水县| 随州市| 项城市| 富宁县| 襄垣县| 肥东县| 新平| 古丈县| 荔波县|