linux 正則表達式 與 shell script


內容源於: 鳥哥的linux私房菜

鏈接如下:

正規表示法與文件格式化處理

學習 Shell Scripts 


目錄

正則表達式 
shell script 


正則表達式

相關資料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) 的權限,然后:
    1. 絕對路徑:使用 /home/dmtsai/shell.sh 來下達命令;
    2. 相對路徑:假設工作目錄在 /home/dmtsai/ ,則使用 ./shell.sh 來運行
    3. 變量『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" ]
[□"$HOME"□==□"$MAIL"□]
  ↑        ↑   ↑       ↑
  • 在中括號 [] 內的每個組件都需要有空白鍵來分隔;
  • 在中括號內的變量,最好都以雙引號括號起來;
  • 在中括號內的常數,最好都以單或雙引號括號起來.

錯誤例子:  [ $name == "VBird" ]   等價於   [ VBird Tsai == "VBird" ] 

  • && 代表 AND ;
  • || 代表 or ;
[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替換為
[ "$yn" == "Y" ] || [ "$yn" == "y"]

 

Shell script 的默認變量($0, $1...)

/path/to/scriptname opt1 opt2 opt3 opt4
$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 的變量內容在回圈工作時:

    1. 第一次回圈時, $var 的內容為 con1 ;
    2. 第二次回圈時, $var 的內容為 con2 ;
    3. 第三次回圈時, $var 的內容為 con3 ;
    4. ....
  • for...do...done 
    for (( 初始值; 限制值; 運行步階 ))
    do
    程序段
    done
    • 初始值:某個變量在回圈當中的起始值,直接以類似 i=1 配置好;
    • 限制值:當變量的值在這個限制值的范圍內,就繼續進行回圈.例如 i<=100;
    • 運行步階:每作一次回圈時,變量的變化量.例如 i=i+1.

 

函數 

利用 function 功能

function fname() {
程序段
}
  • 因為 shell script 的運行方式是由上而下,由左而右, 因此在 shell script 當中的 function 的配置一定要在程序的最前面
  • function 也是擁有內建變量的~他的內建變量與 shell script 很類似, 函數名稱代表示 $0 ,而后續接的變量也是以 $1, $2... 來取代的

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM