1. 程式人生 > >兄弟連Linux(九)--Shell程式設計

兄弟連Linux(九)--Shell程式設計

1、正則表示式

1.1 正則表示式與萬用字元(萬用字元有 * ? [])

正則表示式用來在檔案中匹配符合條件的字串,正則是包含匹配grepawksed等命令可以支援正則表示式

萬用字元用來匹配符合條件的檔名,萬用字元是完全匹配lsfin·

       *            前一個字元匹配0次或任意多次

.             匹配除了換行符外任意一個字元

^            匹配行首。例如:^hello會匹配以hello開頭的行

$            匹配行尾。例如:hello$會匹配以hello結尾的行

[]            匹配中括號中指定的任意一個字元。只匹配一個字元。例如:[aoeiu]匹配任意一個母音字母,[0-9]匹配任意一個數字,[a-z][0-9]匹配小寫字母和一個數字構成的兩位字元。

[^]          匹配除中括號中的字元以外的任意一個字元。例如:[^0-9]匹配任意一位非數字字元。[^a-z]表示任意一位非小寫字母。

\             轉義符。用於取消特殊符號的含義

\{n\}       表示其前面的字元恰好出現n次。例如:[0-9]\{4\}匹配4位數字,[1][3-][0-9]\{9\}匹配手機號碼。

\{n,\}      表示其前面的字元出現不少於n次。例如:[0-9]\{2,\}表示兩位及以上的數字

\{n,m\}   表示其前面的字元至少出現n次,最多出現m次。例如:[a-z]\{6,8\}匹配6到8位的小寫字母。

*”前一個字元匹配

0次,或任意多次

       grep “a*” test_rule.txt           匹配所有內容,包括空白行

       grep “aa*” test_rule.txt         匹配至少包含有一個a的行

       grap “aaa*” test_rule.txt        匹配最少包含兩個連續a的字串

       grap “aaaaa*” test_rule.txt     匹配最少包含四個連續a的字串

.”匹配除了換行符外的任意一個字元

       grep “s..d” test_rule.txt         匹配在s和d字母之間一定有兩個字元的單詞

       grep “s.*d” text_rule.txt        匹配在s和d字母之間有任意字元

       grep “.*” text_rule.txt           匹配所有內容

^”匹配行首,“$”匹配行尾

       grep “^M” test_rule.txt         匹配以大寫M開頭的行

       grep “n$” text_rule.txt          匹配以小寫n結尾的行

       grep -n “^$” test_rule.txt              匹配空白行

[]”匹配中括號指定的任意一個字元,只匹配一個字元

       grep “s[ao]id” test_rule.txt    匹配s和i字元中間,不是a,就是o

       grep “[0-9]” test_rule.txt              匹配任意一個數字

       grep “^[a-z]” test_rule.txt      匹配用小寫字母a開頭的行

[^]”匹配除中括號的字元以外的任意一個字元

       grep “^[^a-zA-Z]” test_rule.txt     匹配不用字母開頭的行

       grep “^[^a-z]” test_rule.txt           匹配不用小寫字母開頭的行

\”轉義符

       grep “\.$” test_rule.txt          匹配使用“.”結尾的行

\{n\}”表示其前面的字元恰好出現n

       grep “a\{3\}” test_rule.txt            匹配a字母連續出現3次的字串

       gerp “[0-9]\{3\}” test_rule.txt              匹配包括連續的三個數字的字串

\{n,m\}”匹配其前面的字元至少出現n次,最多出現m

       grep “sa\{1,3\}i” test_rule.txt

2、字元擷取命令

2.1 cut欄位提取命令

       cut -df 檔名

              -d    提取第幾列

              -f     按照指定分隔符分隔列

2.2 pringf命令

       printf ‘輸出型別輸出格式’ 輸出內容

       輸出型別

              %ns        輸出字串。n是數字指代輸出幾個字串

              %ni        輸出整數。n是數字指代輸出幾個數字

              %m.nf    輸出浮點數。m和n是數字,指代輸出的整數位數和小數位數。如%8.2f代表共輸出8位數,其中2位是小數,6位是整數

       輸出格式

              \a     輸出警告聲音

\b    輸出退格鍵,也就是Backspace鍵

\f     清除螢幕

\n    換行

\r     回車,也就是Enter鍵

\t     水平輸出退格鍵,也就是Tab鍵

\v    垂直輸出退格鍵,也就是Tab鍵

2.3 awk命令

$ awk ‘條件1{動作1}條件2{動作2}…’ 檔名

條件(Pattern):

       一般使用關係表示式作為條件

              x>10       判斷變數x是否大於10

              x>=10     大於等於

              x<=10     小於等於

動作(Action):

       格式化輸出

       流程控制語句

BEGIN

       $ awk ‘BEGIN {printf “This is a transcript \n”} {printf $2 “\t” $6 “\n”}’ student.txt

FS內建變數

       $ cat /etc/passwd | grep “/bin/bash” | awk ‘BEGIN {FS=”:”} {printf $1 “\t” $3 “\n”}’

END

       $ awk ‘END {printf “The End \n”}{printf $2 “\t” $6 “\n”}’ student.txt

關係運算符

       $ cat student.txt | grep -v Name| awk ‘$6 >=87 {printf $2 “\n”}’

2.4 sed命令

2.4.1 sed命令

       sed是一種幾乎包括在所有UNIX平臺(包括Linux)的輕量級流編輯器。sed主要是用來將資料進行選取、替換、刪除、新增的命令。

       $ sed -nei ‘[動作]’ 檔名

              -n    一般sed命令會把所有資料都輸出到螢幕,如果加入此選擇,則只會把經過sed命令處理的行輸出到螢幕

-e    允許對輸入資料應用多條sed命令編輯

-i     用sed的修改結果直接修改讀取資料的檔案,而不是由螢幕輸出

       動作:

              a \    追加,在當前行後新增一行或多行。新增多行時,出最後一行外,每行末尾需要用“\”代表資料未完結

              c \    行替換,用c後面的字串替換原資料行,替換多行時,除最後一行外,每行末尾需用“\”代表資料未完結

i \    插入,在當前行前插入一行或多行。插入多行時,出最後一行外,每行末尾需要用“\”代表資料未完結

d     刪除,刪除指定的行

p     列印,輸出指定的行

s      字串替換,用一個字串替換另一個字串。格式為“行範圍s/舊字串/新字串/g”(和vim中的替換格式類似)

2.4.2 行資料操作

       $ sed -n ‘2p’ student.txt

       $ sed ‘2,4d’ student.txt

       $ sed ‘2a hello’ student.txt

       $ sed ‘2i hello\

       world’ student.txt

       $ sed ‘2c No such person’ student.txt

2.4.3 字串替換

       $ sed ‘s/舊字串/新字串/g’ 檔名

       $ sed -i ‘3s/74/99/g’ student.txt

       $ sed -e ‘s/Liming//g; s/Gao//g’ student.txt

3、字元處理命令

3.1 排序命令sort

       $ sort -fnrtk 檔名

              -f            忽略大小寫

-n           以數值型進行排序,預設使用字串型排序

-r            反向排序

-t            指定分隔符,預設的分隔符是製表符

-k n[,m]  按照指定的欄位範圍排序。從第n欄位開始,m欄位結束(預設到行尾)

       $ sort /etc/passwd          排序使用者資訊檔案

       $ sort -r /etc/passwd       反向排序

       $ sort -t “:” -k 3,3 /etc/passwd      指定分隔符是“:”,用第三欄位開頭,第三欄位結尾排序,就是隻用第三欄位排序

       $ sort -n -t “:” -k 3,3 /etc/passwd

3.2 統計命令 wc

       $ wc -lwm 檔名

              -l     只統計行數

-w   只統計單詞數

-m   只統計字元數

4、條件判斷

4.1 按照檔案型別進行判斷

       -b 檔案  判斷該檔案是否存在,並且是否為塊裝置檔案(是塊裝置檔案為真)

-c 檔案   判斷該檔案是否存在,並且是否為字元裝置檔案(是字元裝置檔案為真)

-d 檔案判斷該檔案是否存在,並且是否為目錄檔案(是目錄為真)

-e 檔案判斷該檔案是否存在(存在為真)

-f 檔案判斷該檔案是否存在,並且是否為普通檔案(是普通檔案為真)

-L 檔案  判斷該檔案是否存在,並且是否為符號連結檔案(是符號連結檔案為真)

-p 檔案  判斷該檔案是否存在,並且是否為管道檔案(是管道檔案為真)

-s 檔案   判斷該檔案是否存在,並且是否為非空(非空為真)

-S 檔案  判斷該檔案是否存在,並且是否為套接字檔案(是套接字檔案為真)

兩種判斷格式

       $ test -e /root/install.log

       $ [ -e /root/install.log ]

       $ echo $?                      檢視上一條命令執行情況

       [ -d /root ] && echo “yes” || echo “no”            第一個判斷命令如果正確執行,則列印“yes”,否則列印“no”

4.2 按照檔案許可權進行判斷

       -r 檔案判斷該檔案是否存在,並且是否該檔案擁有讀許可權(有讀許可權為真)

-w 檔案判斷該檔案是否存在,並且是否該檔案擁有寫許可權(有寫許可權為真)

-x 檔案判斷該檔案是否存在,並且是否該檔案擁有執行許可權(有執行許可權為真)

-u 檔案  判斷該檔案是否存在,並且是否該檔案擁有SUID許可權(有SUID許可權為真)

-g 檔案  判斷該檔案是否存在,並且是否該檔案擁有SGID許可權(有SGID許可權為真)

-k 檔案  判斷該檔案是否存在,並且是夠該檔案擁有SBit許可權(有SBit許可權為真)

4.3 兩個檔案之間進行比較

       檔案1 -nt 檔案2  判斷檔案1的修改時間是否比檔案2的新(如果新則為真)

       檔案1 -ot 檔案2  判斷檔案1的修改時間是否比檔案2的舊(如果舊則為真)

       檔案1 -ef 檔案2  判斷檔案1和檔案2的Inode號是否一致,可以理解為兩個檔案是否為同一個檔案。這個判斷能用於判斷硬連結是很好的方法

4.4 兩個整數之間的比較

       整數1 -eq 整數2         判斷整數1是否和整數2相等(相等為真)

       整數1 -ne 整數2         判斷整數1是否和整數2不相等(不相等為真)

       整數1 -gt 整數2         判斷整數1是否大於整數2(大於為真)

       整數1 -lt 整數2          判斷整數1是否小於整數2(小於為真)

       整數1 -ge 整數2         判斷整數1是否大於等於整數2(大於等於為真)

       整數1 -le 整數2          判斷整數1是否小於等於整數2(小於等於為真)

4.5 字串的判斷

       -z 字串             判斷字串是否為空(為空返回真)

       -n 字串             判斷字串是否為非空(非空返回真)

       字串1==字串2     判斷字串1是否和字串2相等(相等返回真)

       字串1!=字串2    判斷字串1是否和字串年不相等(不相等返回真)

       name=sc         給name變數負責

       [ -z “$name” ] && echo ”yes” || echo “no”          判斷name變數是否為空,因為不為空,所以返回no

4.6 多重條件判斷

       判斷1 -a 判斷2           邏輯與,判斷1和判斷2都成立,最終結果才成立

       判斷1 -o 判斷2          邏輯或,判斷1或判斷2有一個成立,最終結果就為真

       !判斷                         邏輯非,使原始的判斷式取反

       aa=11

       [ -n “$aa” -a “$aa” -gt 23 ] && echo “yes” || echo “no”      判斷變數aa是否有值,同時判斷變數aa的值是否大於23,所以雖然第一個判斷值為真,返回的結果也是假

5、流程控制

5.1 if語句

5.1.1 單分支if條件語句

       if [ 條件判斷式 ] ; then

              程式

       fi

       或者

       if [ 條件判斷式 ]

              then

                     程式

       fi

單分支條件語句需要注意幾個點:

              if語句使用fi結尾,和一般語言使用大括號結尾不同

              [ 條件判斷式 ]就是使用test命令判斷,所以中括號和條件判斷式之間必須有空格

              then後面跟符合條件之後執行的程式,可以放在[]中,用“;”分隔。也可以換行寫入,就不需要“;”了。

       #!/bin/bash

       #統計根分割槽使用率

       #Author:shenchao(Email:[email protected]

       rate=$(df -h | grep “/dev/sda3” | awk ‘{print $5}’ | cut -d “%” -f1)  #把根分割槽使用率作為變數值賦予變數rate

       if [ $rate -ge 80 ]

              then

                     echo “Warning! /dev/sda3 is full!!”

              fi

5.1.2 雙分支if條件語句

       if [ 條件判斷式 ]

              then

                     條件成立時,執行的程式

              else

                     條件不成立時,執行的另一個成粗

       fi

       #!/bin/bash

       #備份MySQL資料庫

       #Author: shenchao (Email:[email protected])

       ntpdate asia.pool.ntp.org &>/dev/null          同步系統時間

       date=$(date +%Y%M%d)            把當前系統時間按照“年月日”格式賦予變數date

       size=$(du -sh /var/lib/mysql)        統計mysql資料庫大小,並把大小賦予size變數

if [ -d /tmp/dbbak ]

       then

              echo “Date : $date!” > tmp/dabak/dbinfo.txt

              echo “Data size : $size” >> /tmp/dbbak/dbinfo.txt

              cd /tmp/dbbak

              tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &> /dev/null

              rm -rf /tmp/dbbak/dbinfo.txt

       else

              mkdir /tmp/dbbak

              echo “Date: $date!” > /tmp/dbbak/dbinfo.txt

              echo “Date size : $size” >> /tmp/dbbak/dbinfo.txt

              cd /tmp/dbbak

              tar -zcf mysql-lib-$date.tar.gz /varlib/mysql dbinfo.txt &> /dev/null

              rm -rf /tmp/dbbak/dbinfo.txt

#!/bin/bash

#判斷Apache是否啟動

#Author:shenchao (Email:[email protected])

prot=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk ‘{print $2}’)  使用nmap命令掃描伺服器,並擷取apache服務的狀態,賦予變數port

if [ “$port” == “open” ]

       then

              echo “$(date) httpd is ok!” >> /tmp/autostart-acc.log

       else

              /etc/rc.d/init.d/httpd start &>/dev/null

              echo “$(date) restart http !!” >> /tmp/autostart-err.log

       fi

5.1.3 多分支if條件語句

if [ 條件判斷式1 ]

       then

              當條件判斷式1成立時,執行程式1

elif [ 條件判斷式2 ]

       then

              當條件判斷式2成立時,執行程式2

…省略更多條件…

else

       當所有條件都不成立時,最後執行此程式

fi

#!/bin/bash

#判斷使用者輸入的是什麼檔案

# Author: shenchao (Email: [email protected])

read -p “Please input a filename: ” file         接收鍵盤的輸入並賦予變數file

if [ -z “$file” ]              判斷file變數是否為空

       then

              echo “Error, please input a filename”

              exit 1

elif [ ! -e “$file” ]         判斷file的值是否存在

       then

              echo “Your input is not a file”

              exit 2

elif [ -f “$file” ]            判斷file的值是否為普通檔案

       then

              echo “$file is a regulare file!”

elif[ -d “$file” ]            判斷file的值是否為目錄檔案

       then

              echo “$file is directory!”

else

       echo “$file is an other file!”

fi

5.2 case語句

多分支case條件語句

       case語句和if…elif…else語句一樣都是多分支條件語句,不過和if多分支條件語句不同的是,case語句只能判斷一種條件關係,而if語句可以判斷多種條件關係。

       case $變數名 in

              “值1”)

                     如果變數的值等於值1,則執行程式1

                     ;;

              “值2”)

                     如果變數的值等於值2,則執行程式2

                     ;;

              …省略其他分支…

              *)

                     如果變數的值都不是以上的值,則執行此程式

                     ;;

       esac

5.3 for迴圈

語法一

       for 變數 in 值1值2值3

              do

                     程式

              done

語法二

       for ((初始值;迴圈控制條件;變數變化))

              do

                     程式

              done

5.4 while迴圈和until迴圈

5.4.1 while迴圈

       while迴圈是不定迴圈,也稱為條件迴圈。只要條件判斷式成立,迴圈就會一直繼續,直到條件判斷式不成立,迴圈才會停止。這就和for的固定迴圈不太一樣了。

       while [ 條件判斷式 ]

              do

                     程式

              done

5.4.2 until迴圈

       until迴圈,和while迴圈相反,until迴圈時只要條件判斷式不成立則進行迴圈,並執行迴圈程式。一旦迴圈條件成立,則終止迴圈。

       until [ 條件判斷式 ]

              do

                     程式

              done