函數,正則表達
本節內容
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個字符 echo "aadadccc" | egrep "a{2}"
{n,}匹配花括號前面字符至少 n個字符 echo "aadadccc" | egrep "a{1}"
{n,9m}
匹配花、-括號前面字符至少 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
總結
正則表達式
一、字符匹配
點匹配任意單個字符
例子
[root@006 ~]# grep "r.t" 1
operator:x:11:0:operator:/root:/sbin/nologin
[root@006 ~]# grep "r..t" 1
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
^開頭
例子
[root@006 ~]# grep "^root" 1
root:x:0:0:root:/root:/bin/bash
$后別
例子
[root@006 ~]# grep "sync$" 1
sync:x:5:0:sync:/sbin:/bin/sync
空號
[root@006 ~]# grep -v "^$" 1
二、次數匹配
*后邊為一定。前別0個或多個
[root@006 ~]# grep -n "n*c" 1
6:sync:x:5:0:sync:/sbin:/bin/sync
.* 匹配開頭和結尾
[root@006 ~]# grep -n "r.*t" 1
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[ ] 匹配是單個字符【a-zA-Z0-9】
\{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:] 控00
[: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. 過濾出包含大寫字母的行
cat /etc/init.d/functions | grep "[A-Z]"
2. 匹配非數字字符
cat /etc/init.d/functions | grep "[^0-9]"
3. 過濾出一行中a在前,b在后的行
cat /etc/init.d/functions | grep "a.*b"
4. 匹配a和b之間有最少2個c最多5個c的行
5. 過濾出以# 為開頭,且第二個字符是空格的行
grep "^# " /etc/init.d/functions
6.過濾出行首和行位字母相同的行
Grep "^\([a-z]).*\1$"
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"
來自 <https://www.cnblogs.com/kenken2018/p/10229140.html>