內容源於: 鳥哥的linux私房菜
鏈接如下:
目錄
正則表達式
相關資料: http://deerchao.net/tutorials/regex/regex.htm
含義:
正則表達式就是處理字串的方法,他是以行為單位來進行字串的處理行為, 正則表達式透過一些特殊符號的輔助,可以讓使用者輕易的達到『搜尋/刪除/取代』某特定字串的處理程序
基礎正則表達式字符匯整 (characters)
RE 字符 | 意義與范例 |
^word | 意義:待搜尋的字串(word)在行首! 范例:搜尋行首為 # 開始的那一行,並列出行號grep -n '^#' regular_express.txt |
word$ | 意義:待搜尋的字串(word)在行尾! 范例:將行尾為 ! 的那一行列印出來,並列出行號grep -n '!$' regular_express.txt |
. | 意義:代表『一定有一個任意字節』的字符! 范例:搜尋的字串可以是 (eve) (eae) (eee) (e e), 但不能僅有 (ee) !亦即 e 與 e 中間『一定』僅有一個字節,而空白字節也是字節!grep -n 'e.e' regular_express.txt |
\ | 意義:跳脫字符,將特殊符號的特殊意義去除! 范例:搜尋含有單引號 ' 的那一行!grep -n \' regular_express.txt |
* | 意義:重復零個到無窮多個的前一個 RE 字符 范例:找出含有 (es) (ess) (esss) 等等的字串,注意,因為 * 可以是 0 個,所以 es 也是符合帶搜尋字串.另外,因為 * 為重復『前一個 RE 字符』的符號, 因此,在 * 之前必須要緊接著一個 RE 字符喔!例如任意字節則為 『.*』 !grep -n 'ess*' regular_express.txt |
[list] | 意義:字節集合的 RE 字符,里面列出想要擷取的字節! 范例:搜尋含有 (gl) 或 (gd) 的那一行,需要特別留意的是,在 [] 當中『謹代表一個待搜尋的字節』, 例如『 a[afl]y 』代表搜尋的字串可以是 aay, afy, aly 即 [afl] 代表 a 或 f 或 l 的意思!grep -n 'g[ld]' regular_express.txt |
[n1-n2] | 意義:字節集合的 RE 字符,里面列出想要擷取的字節范圍! 范例:搜尋含有任意數字的那一行!需特別留意,在字節集合 [] 中的減號 - 是有特殊意義的,他代表兩個字節之間的所有連續字節!但這個連續與否與 ASCII 編碼有關,因此,你的編碼需要配置正確(在 bash 當中,需要確定 LANG 與 LANGUAGE 的變量是否正確!) 例如所有大寫字節則為 [A-Z]grep -n '[A-Z]' regular_express.txt |
[^list] | 意義:字節集合的 RE 字符,里面列出不要的字串或范圍! 范例:搜尋的字串可以是 (oog) (ood) 但不能是 (oot) ,那個 ^ 在 [] 內時,代表的意義是『反向選擇』的意思. 例如,我不要大寫字節,則為 [^A-Z].但是,需要特別注意的是,如果以 grep -n [^A-Z] regular_express.txt 來搜尋,卻發現該文件內的所有行都被列出,為什么?因為這個 [^A-Z] 是『非大寫字節』的意思, 因為每一行均有非大寫字節,例如第一行的 "Open Source" 就有 p,e,n,o.... 等等的小寫字grep -n 'oo[^t]' regular_express.txt |
\{n,m\} | 意義:連續 n 到 m 個的『前一個 RE 字符』 意義:若為 \{n\} 則是連續 n 個的前一個 RE 字符, 意義:若是 \{n,\} 則是連續 n 個以上的前一個 RE 字符! 范例:在 g 與 g 之間有 2 個到 3 個的 o 存在的字串,亦即 (goog)(gooog)grep -n 'go\{2,3\}g' regular_express.txt |
特殊字符的特殊意義
特殊符號 | 代表意義 |
[:alnum:] | 代表英文大小寫字節及數字,亦即 0-9, A-Z, a-z |
[:alpha:] | 代表任何英文大小寫字節,亦即 A-Z, a-z |
[:blank:] | 代表空白鍵與 [Tab] 按鍵兩者 |
[:cntrl:] | 代表鍵盤上面的控制按鍵,亦即包括 CR, LF, Tab, Del.. 等等 |
[:digit:] | 代表數字而已,亦即 0-9 |
[:graph:] | 除了空白字節 (空白鍵與 [Tab] 按鍵) 外的其他所有按鍵 |
[:lower:] | 代表小寫字節,亦即 a-z |
[:print:] | 代表任何可以被列印出來的字節 |
[:punct:] | 代表標點符號 (punctuation symbol),亦即:" ' ? ! ; : # $... |
[:upper:] | 代表大寫字節,亦即 A-Z |
[:space:] | 任何會產生空白的字節,包括空白鍵, [Tab], CR 等等 |
[:xdigit:] | 代表 16 進位的數字類型,因此包括: 0-9, A-F, a-f 的數字與字節 |
延伸正則表達式
RE 字符 | 意義與范例 |
+ | 意義:重復『一個或一個以上』的前一個 RE 字符 范例:搜尋 (god) (good) (goood)... 等等的字串. 那個 o+ 代表『一個以上的 o 』所以,底下的運行成果會將第 1, 9, 13 行列出來.egrep -n 'go+d' regular_express.txt |
? | 意義:『零個或一個』的前一個 RE 字符 范例:搜尋 (gd) (god) 這兩個字串. 那個 o? 代表『空的或 1 個 o 』所以,上面的運行成果會將第 13, 14 行列出來. 有沒有發現到,這兩個案例( 'go+d' 與 'go?d' )的結果集合與 'go*d' 相同? 想想看,這是為什么喔! ^_^egrep -n 'go?d' regular_express.txt |
| | 意義:用或( or )的方式找出數個字串 范例:搜尋 gd 或 good 這兩個字串,注意,是『或』! 所以,第 1,9,14 這三行都可以被列印出來喔!那如果還想要找出 dog 呢?egrep -n 'gd|good' regular_express.txt egrep -n 'gd|good|dog' regular_express.txt |
() | 意義:找出『群組』字串 范例:搜尋 (glad) 或 (good) 這兩個字串,因為 g 與 d 是重復的,所以, 我就可以將 la 與 oo 列於 ( ) 當中,並以 | 來分隔開來,就可以啦!egrep -n 'g(la|oo)d' regular_express.txt |
()+ | 意義:多個重復群組的判別 范例:將『AxyzxyzxyzxyzC』用 echo 叫出,然后再使用如下的方法搜尋一下!echo 'AxyzxyzxyzxyzC' | egrep 'A(xyz)+C' 上面的例子意思是說,我要找開頭是 A 結尾是 C ,中間有一個以上的 "xyz" 字串的意思~ |
shell script
shell script 是利用 shell 的功能所寫的一個『程序 (program)』,這個程序是使用純文字檔,將一些 shell 的語法與命令(含外部命令)寫在里面, 搭配正規表示法、管線命令與數據流重導向等功能,以達到我們所想要的處理目的.
注意事項
- 命令的運行是從上而下、從左而右的分析與運行;
- 命令的下達就如同第五章內提到的: 命令、選項與參數間的多個空白都會被忽略掉;
- 空白行也將被忽略掉,並且 [tab] 按鍵所推開的空白同樣視為空白鍵;
- 如果讀取到一個 Enter 符號 (CR) ,就嘗試開始運行該行 (或該串) 命令;
- 至於如果一行的內容太多,則可以使用『 \[Enter] 』來延伸至下一行;
- 『 # 』可做為注解!任何加在 # 后面的數據將全部被視為注解文字而被忽略!
運行方式
- 直接命令下達: shell.sh 文件必須要具備可讀與可運行 (rx) 的權限,然后:
- 絕對路徑:使用 /home/dmtsai/shell.sh 來下達命令;
- 相對路徑:假設工作目錄在 /home/dmtsai/ ,則使用 ./shell.sh 來運行
- 變量『PATH』功能:將 shell.sh 放在 PATH 指定的目錄內,例如: ~/bin/
- 以 bash 程序來運行:透過『 bash shell.sh 』或『 sh shell.sh 』來運行
撰寫 shell script 的良好習慣創建
- script 的功能;
- script 的版本資訊;
- script 的作者與聯絡方式;
- script 的版權宣告方式;
- script 的 History (歷史紀錄);
- script 內較特殊的命令,使用『絕對路徑』的方式來下達;
- script 運行時需要的環境變量預先宣告與配置.
script 的運行方式差異
- 利用直接運行的方式來運行 script
當你使用直接運行的方法來處理時,系統會給予一支新的 bash 讓我們來運行 shell script 里面的命令,因此你的自定義的變量在 shell script 的 bash 中是不存在的因為它只會繼承調用它的 bash 的環境變量而不會繼承它的自定義變量.直到 shell script 運行完畢后系統返回到調用 shell script 的 bash 中時你將可以繼續運用的你自定義變量
- 利用 source 來運行腳本:在父程序中運行
利用source 運行腳本時候 shell script其實是在調用它的 bash 下運行的,所以它擁有調用它的 bash 中的環境變量和自定義變量.即source 對 script 的運行方式可以使用底下的圖示來說明!
利用判斷符號 [ ]
[□"$HOME"□==□"$MAIL"□]
↑ ↑ ↑ ↑
- 在中括號 [] 內的每個組件都需要有空白鍵來分隔;
- 在中括號內的變量,最好都以雙引號括號起來;
- 在中括號內的常數,最好都以單或雙引號括號起來.
錯誤例子: [ $name == "VBird" ] 等價於 [ VBird Tsai == "VBird" ]
- && 代表 AND ;
- || 代表 or ;
上式可替換為
[ "$yn" == "Y" ] || [ "$yn" == "y"]
Shell script 的默認變量($0, $1...)
$0 $1 $2 $3 $4
- $0 :運行的腳本檔名
- $Num :腳本接收參數,$1表示第一個參數,$2表示第二個參數,依次類推
- $# :代表后接的參數『個數』,以上表為例這里顯示為『 4 』;
- $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每個變量是獨立的(用雙引號括起來);
- $* :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字節,默認為空白鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意.
shift:造成參數變量號碼偏移
[root@www scripts]# vi sh08.sh
#!/bin/bash
# Program:
# Program shows the effect of shift function.
# History:
# 2009/02/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift # 進行第一次『一個變量的 shift 』
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
shift 3 # 進行第二次『三個變量的 shift 』
echo "Total parameter number is ==> $#"
echo "Your whole parameter is ==> '$@'"
這玩意的運行成果如下:
[root@www scripts]# sh sh08.sh one two three four five six <==給予六個參數
Total parameter number is ==> 6 <==最原始的參數變量情況
Your whole parameter is ==> 'one two three four five six'
Total parameter number is ==> 5 <==第一次偏移,看底下發現第一個 one 不見了
Your whole parameter is ==> 'two three four five six'
Total parameter number is ==> 2 <==第二次偏移掉三個,two three four 不見了
Your whole parameter is ==> 'five six'
選擇
- if ...
if [ 條件判斷式 ]; then
當條件判斷式成立時,可以進行的命令工作內容;
fi <==將 if 反過來寫,就成為 fi 啦!結束 if 之意! - if ... else ...
if [ 條件判斷式 ]; then
當條件判斷式成立時,可以進行的命令工作內容;
else
當條件判斷式不成立時,可以進行的命令工作內容;
fi - if ... elif ... elif ... else
if [ 條件判斷式一 ]; then
當條件判斷式一成立時,可以進行的命令工作內容;
elif [ 條件判斷式二 ]; then
當條件判斷式二成立時,可以進行的命令工作內容;
else
當條件判斷式一與二均不成立時,可以進行的命令工作內容;
fi - case ..... esac
case $變量名稱 in <== 關鍵字為 case ,還有變量前有錢字號
"第一個變量內容") <== 每個變量內容建議用雙引號括起來,關鍵字則為小括號 )
程序段
;; <== 每個類別結尾使用兩個連續的分號來處理!
"第二個變量內容")
程序段
;;
*) <== 最后一個變量內容都會用 * 來代表所有其他值
不包含第一個變量內容與第二個變量內容的其他程序運行段
exit 1
;;
esac
例子:
范例:if else 的運用
[root@www scripts]# cp sh06-2.sh sh06-3.sh
[root@www scripts]# vi sh06-3.sh
#!/bin/bash
# Program:
# This program shows the user's choice
# History:
# 2005/08/25 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
read -p "Please input (Y/N): " yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!"
else
echo "I don't know what your choice is"
fi
范例二:case ..... esac 的運用
[root@www scripts]# vi sh09-2.sh
#!/bin/bash
# Program:
# Show "Hello" from $1.... by using case .... esac
# History:
# 2005/08/29 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
case $1 in
"hello")
echo "Hello, how are you ?"
;;
"")
echo "You MUST input parameters, ex> {$0 someword}"
;;
*) # 其實就相當於萬用字節,0~無窮多個任意字節之意!
echo "Usage $0 {hello}"
;;
esac
循環
- 滿足時循環
『當 condition 條件成立時,就進行回圈,直到 condition 的條件不成立才停止』
while [ condition ] <== 中括號內的狀態就是判斷式
do <== do 是回圈的開始!
程序段落
done <== done 是回圈的結束 - 滿足時結束
『當 condition 條件成立時,就終止回圈, 否則就持續進行回圈的程序段.』
until [ condition ]
do
程序段落
done - 固定回圈
for...do...done
for var in con1 con2 con3 ...
do
程序段
done以上面的例子來說,這個 $var 的變量內容在回圈工作時:
- 第一次回圈時, $var 的內容為 con1 ;
- 第二次回圈時, $var 的內容為 con2 ;
- 第三次回圈時, $var 的內容為 con3 ;
- ....
- for...do...done
for (( 初始值; 限制值; 運行步階 ))
do
程序段
done- 初始值:某個變量在回圈當中的起始值,直接以類似 i=1 配置好;
- 限制值:當變量的值在這個限制值的范圍內,就繼續進行回圈.例如 i<=100;
- 運行步階:每作一次回圈時,變量的變化量.例如 i=i+1.
函數
利用 function 功能
程序段
}
- 因為 shell script 的運行方式是由上而下,由左而右, 因此在 shell script 當中的 function 的配置一定要在程序的最前面
- function 也是擁有內建變量的~他的內建變量與 shell script 很類似, 函數名稱代表示 $0 ,而后續接的變量也是以 $1, $2... 來取代的