Bash
將布爾比較中的值分配給變數
我有一個腳本,我需要在其中對字元串變數的內容進行所有可能的比較。每種組合都需要對變數內容採用不同的方法,因此如下所示:
if $a contains "a" AND "b" AND "c"; then do x elif $a contains "a" AND "b" but NOT "c"; then do y elif $a contains "b" AND "c" but NOT "a"; then do z ...
據我所知,這樣做的方法是構造一個像這樣的 if 條件:
if [[ $A == *"b"* ]] && [[ $A == *"c"* ]] && [[ $A == *"d"* ]] elif [[ $A == *"b"* ]] && [[ $A == *"c"* ]] elif [[ $A == *"c"* ]] && [[ $A == *"d"* ]] elif [[ $A == *"b"* ]] && [[ $A == *"d"* ]] elif [[ $A == *"b"* ]] elif [[ $A == *"c"* ]] elif [[ $A == *"d"* ]] fi
但這當然太複雜了,因為我的變數($A)和子字元串(b,c,d)的名稱比這長得多。所以我想看看是否有辦法將條件表達式的內容保存到變數中:
contains_b= *a condition for [[ $A == *"b"* ]]*; echo $contains_b
-> 真 | 錯誤的我只在這裡找到了回复[
contains_b=$(! [ "$A" = *"b"* ]; echo $?)
]; 但是,$contains_b -> 0
在隨後的條件句中不起作用,因為:
if $contains_b; then do x; fi
->bash: [0]: command not found
所以我能想到的唯一解決方案是手動完成:
if [[ $A == *"b"* ]]; then contains_b=true else contains_b=false fi
但是,我最終會執行三個 if 語句來獲取三個變數,以及每個不同組合的其他 7 個比較。
我想知道是否有不同/更有效的方法。如果沒有,您對進行這些多重比較的另一種方法有什麼建議嗎?我覺得我把它弄得太複雜了……
感謝您的任何幫助。
創建一個二進制遮罩,然後對其進行操作。這樣做的好處是每個測試只執行一次,並將測試與對測試結果的操作分開。
請注意,程式碼將模式用作擴展的正則表達式。要將它們作為字元串進行比較,請使用
[[ $string == *"$pattern"* ]]
代替
[[ $string =~ $pattern ]]
在下面的程式碼中。
patterns=( a b c ) string='abba' mask=0; i=0 for pattern in "${patterns[@]}"; do if [[ $string =~ $pattern ]]; then # setting the i:th bit from the right to one mask=$(( mask | (1 << i) )) fi i=$(( i + 1 )) done case $mask in 0) echo no match ;; 1) echo first pattern matched ;; 2) echo second pattern matched ;; 3) echo first and second pattern matched ;; 4) echo third pattern matched ;; 5) echo first and third pattern matched ;; 6) echo second and third pattern matched ;; 7) echo all patterns matched ;; *) echo error esac
或者,使用帶有 1 和 0 的字元串遮罩(0 表示不匹配,1 表示匹配)。請注意,
mask
下面的字元串與上面程式碼中使用的數字的實際二進製表示相反。patterns=( a b c ) string='abba' unset -v mask for pattern in "${patterns[@]}"; do ! [[ $string =~ $pattern ]] # string concatenation of the exit status of the previous command mask+=$? done case $mask in 000) echo no match ;; 100) echo first pattern matched ;; 010) echo second pattern matched ;; 110) echo first and second pattern matched ;; 001) echo third pattern matched ;; 101) echo first and third pattern matched ;; 011) echo second and third pattern matched ;; 111) echo all patterns matched ;; *) echo error esac
每個腳本的輸出將是
first and second pattern matched
…因為字元串
abba
匹配前兩個模式,a
並且b
.