Bash

測試字元串是否存在於字元串數組中

  • September 23, 2016

我正在編寫一個腳本,將文件中每行的前 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"

引用自:https://unix.stackexchange.com/questions/311801