文字列配列に文字列があるかどうかをテストする

文字列配列に文字列があるかどうかをテストする

私はファイルの各行の最初の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を実行しているので、連想配列が機能するはずです。

ベストアンサー1

基本的なエラーは、実際には連想配列を宣言しないことです。

$ 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がこれをどのように処理するのか、なぜ1つだけ取るのか完全にはわかりませんが、1連想配列ではないと確信しています。man bash(強調)の説明に従って:

name[subscript]=value 構文を使用して変数を割り当てると、インデックス配列が自動的に生成されます。下付き文字は、数値として評価する必要がある算術式として扱われます。インデックス付き配列を明示的に宣言するには、discover -a nameを使用します(以下のSHELL BUILTINコマンドを参照)。 -a name[subscript] ステートメントも許可されます。

連想配列は、-A name ステートメントを使用して生成されます。

したがって、これを試してください。期待どおりに機能します。

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"

おすすめ記事