この SO の投稿で説明されているのとまったく同じ問題があります (「コロンを含む bash 連想配列キー文字列でエラーが発生する」)。https://stackoverflow.com/q/40406187/10639803
解決策は を使用することですdeclare -A
が、これを実行すると、連想配列はグローバルではなくなります。
方法はあるかdeclare -A
そしてそれをグローバルにするのですか?
更新:declare -gA
ここで説明されているように試しました:https://stackoverflow.com/a/21151984/10639803しかし、何らかの理由でうまくいきません。連想配列 (ハッシュマップ) を設定するループを終了するとすぐに、配列が設定解除されます。
実際の bash コードは次のとおりです (ループ内の echo コマンドは、値が実際に抽出され、割り当てられていることを確認するためのものです)。
declare -gA HOSTS_START_MAP
find "$TEMP" -type f -name "debug.log*" -exec grep -F "STARTING HOST " {} \; |
while IFS= read -r HOST_START_LINE; do
if [[ $HOST_START_LINE =~ (.*)(DEBUG)(.*)(STARTING HOST)([ 0-9]*)(.*)(CALCULATION) ]]
then
HOST_START_TIME=$(echo "${BASH_REMATCH[1]}" | xargs)
HOST_NAME=$(echo "${BASH_REMATCH[6]}" | xargs)
# echo ">$HOST_NAME< ... >$HOST_START_TIME<"
HOSTS_START_MAP[$HOST_NAME]=$HOST_START_TIME
# echo $HOST_NAME --- ${HOSTS_START_MAP[$HOST_NAME]}
fi
done
echo ${#HOSTS_START_MAP[@]}
for MYKEY in "${!HOSTS_START_MAP[@]}"; do echo $MYKEY --- ${HOSTS_START_MAP[@]}; done
答え1
発生している問題は、変数の宣言とは関係ありません。変数をサブシェルで設定し、その値が親で使用可能であると想定しているためです。
この効果は、コードと同じ構造ですが、はるかに単純な例を使用してここで確認できます。
a=""
echo find | while read item; do a="$item"; done
echo "a=$a"
幸いなことに、 を使用する場合は、bash
コードを別の形で書き直すことで、簡単な解決策を利用できます。
a=""
while read item; do a="$item"; done < <( echo find )
echo "a=$a"
実際のコードでは、 が未処理の入力を確実に受け取るwhile IFS= read -r item
ようにするためにを使用しますitem
。例ではわかりやすくするために保護を省略しました。
この回答のコメントで、コードの修正版を求められました。テストできないので、最初にここに載せるのをためらったのですが、次のようになるはずです。
#!/bin/bash
#
declare -gA HOSTS_START_MAP
while IFS= read -r HOST_START_LINE; do
if [[ $HOST_START_LINE =~ (.*)(DEBUG)(.*)(STARTING HOST)([ 0-9]*)(.*)(CALCULATION) ]]
then
HOST_START_TIME=$(echo "${BASH_REMATCH[1]}" | xargs)
HOST_NAME=$(echo "${BASH_REMATCH[6]}" | xargs)
# echo ">$HOST_NAME< ... >$HOST_START_TIME<"
HOSTS_START_MAP[$HOST_NAME]=$HOST_START_TIME
# echo $HOST_NAME --- ${HOSTS_START_MAP[$HOST_NAME]}
fi
done < <( find "$TEMP" -type f -name "debug.log*" -exec grep -F "STARTING HOST " {} \; )
echo ${#HOSTS_START_MAP[@]}
for MYKEY in "${!HOSTS_START_MAP[@]}"; do echo $MYKEY --- ${HOSTS_START_MAP[@]}; done