私はファイルの各行の最初の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"