Shell編程(week4_day4)--技術流ken

 

本節內容

 

1. shell函數

2. shell正則表達式

 

shell函數

 

shell中允許將一組命令集合或語句形成一段可用代碼,這些代碼塊稱爲shell函數。給這段代碼起個名字稱爲函數名,後續可以直接調用該段代碼。

 

格式

func() {   #指定函數名

command    #函數體

}

 

實例1:

#!/bin/bash
func() {
echo "This is a function."
}
func

# bash test.sh
This is a function.

Shell 函數很簡單,函數名後跟雙括號,再跟雙大括號。通過函數名直接調用,不加小括號。

 

示例 2:函數返回值

#!/bin/bash
func() {
VAR=$((1+1))
return $VAR
echo "This is a function."
}
func
echo $?

# bash test.sh
2

return 在函數中定義狀態返回值,返回並終止函數,但返回的只能是 0-255 的數字,類似於 exit。

 

示例 3:函數傳參

#!/bin/bash
func() {
echo "Hello $1"
}
func world
# bash test.sh
Hello world

通過 Shell 位置參數給函數傳參。

 

shell正則表達式

 

正則表達式在每種語言中都會有,功能就是匹配符合你預期要求的字符串。

Shell 正則表達式分爲兩種:

  •  基礎正則表達式
  • 擴展正則表達式:擴展的表達式有+、?、| 和()

 

  1. 正則表達式就是爲了處理大量的文本|字符串而定義的一套規則和方法
  2. 通過定義的這些特殊符號的輔助,系統管理員就可以快速過濾,替換或輸出需要的字符串。Linux正則表達式一般以行爲單位處理。

 

正則表達式和通配符有本質區別

 

 

  1. 不需要思考的判斷方法:在三劍客awk,sed,grep,egrep都是正則,其他都是通配符
  2. 區別通配符和正則表達式最簡單的方法:

    (1)文件目錄名===>通配符
              (2)文件內容(字符串,文本【文件】內容)===>正則表達式

 

下面是一些常用的正則表達式符號,我們先拿 grep 工具舉例說明。

注意:在匹配模式中一定要加上引號

 

                  符號                    

                        描述                                                           實例                                

.

匹配任意單個字符(必須存在)

 

例子:l..e

可以表示

love

like

leee

不可以表示的

labcde

le

lee

^

 

匹配前面字符串開頭

 

匹配以 abc 開頭的行:

echo -e "abc\nxyz" |grep ^abc

$

 

匹配前面字符串結尾

 

匹配以 xyz 結尾的行:

echo -e "abc\nxyz" |grep xyz$

*

 

匹配前一個字符的零個或多個

 

a*  表示出現任意個a的情況

a*b 表示b前面有任意個a的情況(包括沒有a的情況)

.* 

表示任意長度的任意字符

例子:過濾出一行中a在前,b在後的行

條件:

包含 a 和 b

字母 a 必須在 b前面

 

# grep --color "a.*b" b.txt

+(擴展正則)

 

表示其前面的字符出現最少一次的情況

 

匹配 abc 和 abcc:

echo -e "abc\nabcc\nadd" |grep -E 'ab+'

匹配單個數字:echo "113" |grep -o '[0-9]'

連續匹配多個數字:echo "113" |grep -E -o '[0-9]+'

?(擴展正則)

 

表示其前面的字符出現最多一次的情況(可以0個)

 

匹配 ac 或 abc:

echo -e "ac\nabc\nadd" |grep -E 'a?c'

[]

 

表示範圍內的一個字符

 

例子:過濾出包含小寫字母的行       grep [a-z] a.txt

例子:過濾出包含大寫字母的行       grep [A-Z] a.txt

例子:過濾出包含數字的行           grep [0-9] a.txt

例子:過濾出包含數字和小寫字母的行 grep [0-9a-z] a.txt

例子:過濾出包含字母asf的行        grep [asf] a.txt

[ .-.]

 

匹配中括號中範圍內的任意一個字符

 

匹配所有字母

echo -e "a\nb\nc" |grep '[a-z]'

[^]

 

匹配[^字符]之外的任意一個字符

 

匹配 a 或 b:

echo -e "a\nb\nc" |grep '[^c-z]'

匹配末尾數字:echo "abc:cde;123" |grep -E

'[^;]+$'

^[^]

 

匹配不是中括號內任意一個字符開頭的行

 

匹配不是#開頭的行:

grep '^[^#]' /etc/httpd/conf/httpd.conf

{n}或者{n,}

 

{n}:表示嚴格匹配n個字符

{n,}匹配花括號前面字符至少 n個字符

 

echo "aadadccc" | egrep "a{2}"

echo "aadadccc" | egrep "a{1}"

{n,m}

 

匹配花括號前面字符至少 n個字符,最多 m 個字符

 

例子:

"ac\{2,5\}b" 匹配a和b之間有最少2個c最多5個c的行

"ac\{,5\}b" 匹配a和b之間有最多5個c的行

"ac\{2,\}b" 匹配a和b之間有最少2個c的行

\<

 

 錨定單詞首部(單詞一般以空格或特殊字符做分隔)

 

# echo "hi,root,iamroot" | grep "\<root"
hi,root,iamroot
# echo "hi,root,iamroot" | grep "root\>"
hi,root,iamroot
# echo "hi,root,iamroot" | grep "\<root\>"
hi,root,iamroot

 

\>

 錨定單詞尾部(單詞一般以空格或特殊字符做分隔,)  

# echo "hi,root,iamroot" | grep "\<root"
hi,root,iamroot
# echo "hi,root,iamroot" | grep "root\>"
hi,root,iamroot
# echo "hi,root,iamroot" | grep "\<root\>"
hi,root,iamroot

()

 

\1  調用前面的第一個分組

 

 

例子:過濾出一行中有兩個相同數字的行

# grep "\([0-9]\).*\1" inittab

 

例子:過濾出行首和行位字母相同的行

# grep "^\([a-z]\).*\1$" inittab

 

|(擴展正則)

 

匹配豎槓兩邊的任意一個

 

 

例子:過濾出cat 或者Cat

 

# grep "cat|Cat" a.txt

 

# grep "(C|c)at" a.txt

 

 

總結

 

正則表達式

 

一、字符匹配

.

[]

[^]

 

二、次數匹配

*

\{m,n\}

 

三、錨定

^

$

\<

\>

 

四、分組

  \(\)

  \1

 

擴展正則表達式

grep -E

egrep

 

一、字符匹配

.

[]

[^]

 

二、次數匹配

*

{m,n}

表示其前面的字符出現最少一次的情況

?表示其前面的字符出現最多一次的情況

 

三、錨定

^

$

\<

\>

 

四、分組

  ()

  \1

  \2

 

五、或

|

 

一.、正則表達式中的{}以及()都需要加上\進行轉義,而擴展正則表達式不需要

二 、|, ?,+是擴展正則獨有的

三、 錨定單詞首部和尾部在擴展正則以及正則中都需要加上\

 

                                  Posix字符                                             

                                         描述                                                   

[:alnum:]

 

等效a-zA-Z0-9

 

[:alpha:]

 

等效a-zA-Z

[:lower:]

等效a-z

 

[:upper:]

等效A-Z

 

[:digit:]

 

等效0-9

[:space:]

匹配任意空白字符,等效\t\n\r\f\v

 

[:graph:]

非空白字符

 

[:blank:]

空格與定位字符

 

[:cntrl:]

控制字符

 

[:print:]

 

可顯示的字符

[:punct:]

標點符號字符

 

[:xdigit:]

十六進制

 

 

注意:使用這些字符的時候需要在外面還要加一個[]括號

說一下[:space:]

[root@ken ~]# cat test    #文本內容
#!/bin/bash
if [ 1 -eq 1 ];
then    echo "yes"
else    echo "no"
fi
AJDLAJDL
LAJLDJA
JDKAJkjskdjklaskj
lsdjal0dlkakm

[root@ken ~]# grep '[[:space:]]' test   #過濾出包含空格的行,[:space:]括號外面還要再包含一個[]
if [ 1 -eq 1 ];
then    echo "yes"
else    echo "no"

[root@ken ~]# grep ' ' test #也可以使用一個空格來代替[:space:] if [ 1 -eq 1 ]; then echo "yes" else echo "no"

 

正則練習

 

使用文件 /etc/init.d/functions ,下面可能有些部分題目匹配不到符合的情況。

1. 過濾出包含大寫字母的行

2. 匹配非數字字符

3. 過濾出一行中a在前,b在後的行

4. 匹配a和b之間有最少2個c最多5個c的行

5. 過濾出以# 爲開頭,且第二個字符是空格的行

6.過濾出行首和行位字母相同的行

7.過濾出第一個字符是#,且第二個字符串是非空字符,而且結尾是數字的行

8.過濾出一行包含相同數字的行/etc/init.d/functions

 

 

 

 

答案:

1. 

[root@ken ~]# grep "[A-Z]"  /etc/init.d/functions 

 

2. 

[root@ken ~]# grep "[^0-9]"  /etc/init.d/functions 

 

3.

[root@ken ~]#  grep  "a.*b" /etc/init.d/functions 

 

4.(匹配不到)

[root@ken ~]# grep "ac\{2,5\}b" /etc/init.d/functions 

 

5.

[root@ken ~]#  grep "^#[[:space:]]" /etc/init.d/functions 

 

6.(匹配不到)

[root@ken ~]# grep "^\([a-z]\).*\1$" /etc/init.d/functions 

 

7.(匹配不到)

[root@ken ~]# grep  "^#[^[:space:]].*[0-9]$" /etc/init.d/functions 

 

8.

[root@ken ~]# egrep ".*([0-9]).*\1" /etc/init.d/functions 

 

補充:shell練習題

 

1. 每一秒鐘輸出/root下的文件至屏幕

2. 打印出包含某個關鍵詞的文件(關鍵詞執行腳本時接收)

3. 統計系統中以.sh結尾的文件總大小,輸出結果以kb爲單位

 

 

 

 

參考答案:

1. 

#!/bin/bash
for file in `ls /root`
do
        echo $file
        sleep 1
done

 

2.

#!/bin/bash
key=$1
for file in `find / -type f`
do
        grep "$key" $file &>/dev/null
        if [ $? -eq 0 ];then
                echo $file
                sleep 1
        fi
done

 

3.

#!/bin/bash
sum=0
for size in `find /root -name "*.sh" -exec ls -l {} \; | cut -d " " -f 5`
do
        let sum+=$size
done
echo "$((sum/1024))kb"

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章