我在Bash中有一個字符串: shell
string="My string"
如何測試它是否包含另外一個字符串? c#
if [ $string ?? 'foo' ]; then echo "It's there!" fi
哪裏??
是我未知的運算符。 我是否使用echo和grep
? bash
if echo "$string" | grep 'foo'; then echo "It's there!" fi
看起來有點笨拙。 ide
我發現常常須要此功能,所以我在.bashrc
使用了一個自制的shell函數,以下所示,它使我能夠根據須要.bashrc
重複使用它,並具備易於記憶的名稱: 函數
function stringinstring() { case "$2" in *"$1"*) return 0 ;; esac return 1 }
要測試$string2
(例如123abcABC )中是否包含$string1
(例如abc ),我只須要運行stringinstring stringinstring "$string1" "$string2"
並檢查返回值,例如 post
stringinstring "$str1" "$str2" && echo YES || echo NO
這也適用: 測試
if printf -- '%s' "$haystack" | egrep -q -- "$needle" then printf "Found needle in haystack" fi
負面測試是: spa
if ! printf -- '%s' "$haystack" | egrep -q -- "$needle" then echo "Did not find needle in haystack" fi
我認爲這種樣式更經典-較少依賴Bash shell的功能。 線程
--
參數是純POSIX偏執狂,用於防止相似於選項的輸入字符串,例如--abc
或-a
。 code
注意:在一個緊湊的循環此代碼會比使用內部擊殼特徵慢得多 ,由於一個(或兩個)獨立的過程將被建立並經由配管鏈接。
# For null cmd arguments checking to_check=' -t' space_n_dash_chars=' -' [[ $to_check == *"$space_n_dash_chars"* ]] && echo found
正如該SO線程主要介紹bash同樣 ,我在此帖子的底部發布了一個大小寫無關的 bash函數。
反正有個人
因爲已經有不少使用Bash特定功能的答案,所以有一種在功能較差的shell下工做的方法,例如busybox :
[ -z "${string##*$reqsubstr*}" ]
實際上,這可使:
string='echo "My string"' for reqsubstr in 'o "M' 'alt' 'str';do if [ -z "${string##*$reqsubstr*}" ] ;then echo "String '$string' contain substring: '$reqsubstr'." else echo "String '$string' don't contain substring: '$reqsubstr'." fi done
這是在bash , dash , ksh和ash (busybox)下進行測試的,結果始終是:
String 'echo "My string"' contain substring: 'o "M'. String 'echo "My string"' don't contain substring: 'alt'. String 'echo "My string"' contain substring: 'str'.
正如@EeroAaltonen要求的,這是相同演示的版本,在相同的shell下進行了測試:
myfunc() { reqsubstr="$1" shift string="$@" if [ -z "${string##*$reqsubstr*}" ] ;then echo "String '$string' contain substring: '$reqsubstr'."; else echo "String '$string' don't contain substring: '$reqsubstr'." fi }
而後:
$ myfunc 'o "M' 'echo "My String"' String 'echo "My String"' contain substring 'o "M'. $ myfunc 'alt' 'echo "My String"' String 'echo "My String"' don't contain substring 'alt'.
注意:您必須轉義或雙引號和/或雙引號:
$ myfunc 'o "M' echo "My String" String 'echo My String' don't contain substring: 'o "M'. $ myfunc 'o "M' echo \"My String\" String 'echo "My String"' contain substring: 'o "M'.
stringContain() { [ -z "${2##*$1*}" ]; }
那是全部人!
那麼如今:
$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi no $ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi yes
...或者若是提交的字符串可能爲空,如@Sjlver所指出,則該函數將變爲:
stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }
或如AdrianGünter的評論所建議,避免使用-o
switche:
stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}
並進行反向測試以使它們更快地運行:
stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}
使用空字符串:
$ if stringContain '' ''; then echo yes; else echo no; fi yes $ if stringContain 'o "M' ''; then echo yes; else echo no; fi no
對於不區分大小寫的測試字符串,只需將每一個字符串轉換爲小寫便可:
stringContain() { local _lc=${2,,} [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}
校驗:
stringContain 'o "M3' 'echo "my string"' && echo yes || echo no no stringContain 'o "My' 'echo "my string"' && echo yes || echo no yes if stringContain '' ''; then echo yes; else echo no; fi yes if stringContain 'o "M' ''; then echo yes; else echo no; fi no
我不肯定要使用if語句,可是用case語句能夠獲得相似的效果:
case "$string" in *foo*) # Do stuff ;; esac