在 bash2.0X 時代,如要使用正規表示式,非得借助於
sed,awk,grep,egrep,ed...等外部程式,但隨著3.0
發行,很多 Linux 的發行版也換上了 bash3.0, FC3 ,FC4
...等的 bash 都是3.0 版.
在這個版本裏,加入了許多新特性,但用途最廣泛可能是
正規表示式的支援.
3.0 在 [[ ]] 這個運算子加入 egrep 形式的 regexp
,再給三個運算符, == , != , =~
== 是等如
!= 不等如
=~ match , 付合(這個等如上面的加在一起,我只用這個 ;))
還有一個新的變量, BASH_REMATCH , 這個變量用來存放
那些 match 的字符,它是一個陣列(array) , 以數字作
下標,由 0 開始,一如 bash 的陣列.
表示式是在 [[ ]] 的運算符的右邊配對,如
#!/bin/bash
# is this a string?
word=$1
if [ $# -eq 0 ] ; then
exit
fi
[[ "$word" =~ '\<[A-Za-z]+\>' ]] && echo 'String.' || echo 'Others.'
[victor@localhost ~]$ sh temp.sh string
String.
[victor@localhost ~]$ sh temp.sh 111
Others.
好了,加入 BASH_REMATCH
#!/bin/bash
# is this a string?
word=$1
if [ $# -eq 0 ] ; then
exit
fi
[[ "$word" =~ '\<[A-Za-z]+\>' ]] && echo 'String.' || echo 'Others.'
: ${BASH_REMATCH:?"no match"}
echo "Match: $BASH_REMATCH"
victor@localhost ~]$ sh temp.sh 111
Others.
temp.sh: line 8: BASH_REMATCH: no match
[victor@localhost ~]$ sh temp.sh who
String.
Match: who
[victor@localhost ~]$
這可看到 BASH_REMATCH 的工作方式了.當 $word 這個變量符合
'\<[A-Za-z]\>' 這個表示式,它便把那個 who 放進 BASH_REMATCH
中,不符的便不存進.
bash 的 regexp 是使用跟 egrep相同的正規表示式,所以就不寫了,
請參考 CU 置頂的文章.
最後我利用這個特性寫了一個名 count.sh 的樣版,它可計算文件某個
字符出現的次數,本來以前需得用 awk, sed 的,在 3.0 以後不用了,也
不必呼叫外部程式,而且相當簡單.
#! /bin/bash
# dep: Bash3.0 or above
# Purpose: Demo
# set Usage , pattern and file
pat=$1 ; file=$2
usage="Usage: ${0##*/} \"word\" file."
msg1="ex: ${0##*/} \"if\" ${0##*/}"
# if argument is not equal to 2 , print Usage and exit
if (( $# != 2 )) ; then
echo -e "$usage\n$msg1" >&2
exit 1
fi
# if $2 is not a regular file , print usage and exit
if [ ! -f "$file" ] ; then
echo -e "$usage\n$msg1" >&2
exit 1
fi
# set counter to zero
count=0
# search around the given file to match the given pattern
for i in $(<$file) ; do
if [[ "$i" =~ "\<$pat\>" ]] ; then
(( count += 1 )) # if matched, increase 1
fi
done
# how many times appeared in $file
echo $count
因功力有限,文章錯漏在所難免,敬請版友更正,謝謝.
網中人 回复于:2005-09-04 02:01:53
不錯呢!
感謝您的分享哦! ^_^
dingyi129 回复于:2005-09-04 09:56:38
新版本啊,还没用过
装一个试试看
|