Bash
測試字元串是否存在於字元串數組中
我正在編寫一個腳本,將文件中每行的前 3 個字母(通過使用 cut 來獲取它們)與數組中的字元串進行比較。我已經環顧四周,但我發現的解決方案在我的系統上不起作用。
現在它看起來像這樣:
weekdays=([Mon]=1 [Tue]=1 [Wed]=1 [Thu]=1 [Fri]=1 [Sat]=1 [Sun]=1) input="/Foo/Bar.log" while read -r line do cutline="$(echo ${line} | cut -c 1-3" if [[ ${weekdays["$cutline"]} ]] then echo "Match" else echo "No Match" fi done < ${input}
這條線被正確切割,但在測試期間有些東西返回了誤報,因為無論前 3 個字母是什麼,它都會返回“匹配”。
當我用 -x 檢查腳本時,它顯示給我,而不是它使用的實際測試
[[ -n 1 ]]
當我用
[ ]
表達式測試它時,它顯示了1
它是否檢查數組中的每個字元而不僅僅是整個單詞,還是有其他問題?
如果沒有問題,是否有另一種方法可以在繼續下一個之前將一行的前 3 個字母與數組中的所有內容進行比較?
附帶說明:我確實在執行 Bash 4,所以關聯數組應該可以工作
基本錯誤是您實際上並未聲明關聯數組:
$ weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1) $ echo ${weekdays[@]} 1 $ echo ${weekdays[0]} 1 $ echo ${weekdays[2]} $
我不完全確定 bash 如何處理它以及為什麼它只需要 a
1
,但我確信這不是一個關聯數組。如man bash
(強調我的)中所述:如果使用語法名稱分配任何變數,則會自動創建索引數組
$$ subscript $$=價值。下標被視為必須計算為數字的算術表達式。要顯式聲明索引數組,請使用 declare -a name(請參閱下面的 SHELL BUILTIN 命令)。聲明 -a 名稱$$ subscript $$也被接受;下標被忽略。 關聯數組是使用 declare -A 名稱創建的。
所以,試試這個,它會像你期望的那樣工作:
declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1)
也就是說,您的腳本比您需要的要復雜一些。這是使用相同方法的更簡單的版本:
#!/bin/bash declare -A weekdays=(["Mon"]=1 ["Tue"]=1 ["Wed"]=1 ["Thu"]=1 ["Fri"]=1 ["Sat"]=1 ["Sun"]=1) input="/Foo/Bar.log" cut -c 1-3 "$input" | while read -r line; do if [[ ${weekdays["$line"]} ]] then echo "Match : $cutline : ${weekdays[$line]}" else echo "No Match" fi done
雖然我可能會這樣做:
#!/bin/bash cut -c 1-3 "$1" | while read -r line; do case $line in "Mon"|"Tue"|"Wed"|"Thu"|"Fri"|"Sat"|"Sun") echo yes;; *) echo no;; esac done
然後,以目標文件名作為參數執行腳本:
script.sh /Foo/Bar.log"