私はそれに慣れておらずKSH
(実際にはちょうど使い始めました)、本質的に2つの格納された配列を比較して、違いを出力するスクリプトを作成するのに問題があります。
AIX 6.1
一緒に走るKSH Version M-11/16/88f
これが私が今まで持っているものです:
#!/bin/ksh
set -A dfArray $(df | awk '{print $7}' | grep -v Mounted)
set -A dsmArray $(cat dsm.sys | grep DOMAIN | awk '{ s=""; for (i = 2; i <= NF; i++) s = s $i " "; print s }')
MAX=$((${#dsmArray[*]}-1))
for a in ${dfArray[*]}
do
COUNT=0
set -A UNMATCHED
for b in ${dsmArray[*]}
do
(( $a != $b )) && \
UNMATCHED[$COUNT]=$a && \
let COUNT+=1
done
(( ${#UNMATCHED[*]} != $MAX )) && \
print ${UNMATCHED[0]}
unset UNMATCHED
done
2つの配列は次のとおりです。
/
/usr
/var
/tmp
...
DSMアレイ:
/home
/opt
/usr
...
現在のスクリプトを実行すると、次のエラーが発生します。
./checkBackup.sh[22]: / != /home : syntax error
私は何が間違っていましたか?おそらく簡単なことだと確信しています。
ありがとうございます!
答え1
文字列値に対して算術平等を実行しようとするとエラーが発生します。
要素がdfArray
あるかどうかを確認する2つの方法は次のとおりです。dsmArray
set -A dfArray / /usr /var /tmp ...
set -A dsmArray /home /opt /usr ...
for a in "${dfArray[@]}"; do
in=false
for b in "${dsmArray[@]}"; do
if [[ $a == $b ]]; then
echo "$a is in dsmArray"
in=true
break
fi
done
$in || echo "$a is not in dsmArray"
done
/ is not in dsmArray
/usr is in dsmArray
/var is not in dsmArray
/tmp is not in dsmArray
... is in dsmArray
あるいは、dsmArray を平坦化し、内部ループを避けます。
for a in "${dfArray[@]}"; do
# all quotes and spaces required below
if [[ " ${dsmArray[*]} " == *" $a "* ]]; then
echo "$a is in dsmArray"
else
echo "$a is not in dsmArray"
fi
done
/ is not in dsmArray
/usr is in dsmArray
/var is not in dsmArray
/tmp is not in dsmArray
... is in dsmArray
解決の鍵はこの部分にあります。[[ " ${dsmArray[*]} " == *" $a "* ]]
" ${dsmArray[*]} "
- 引用した場合、
"${ary[*]}"
結果は最初の文字に関連付けられた配列の個々の要素で構成される単一の文字列です。$IFS
- デフォルトは
$IFS
3文字です:スペース、タブ、改行 - 先頭と末尾の引用符を使用して文字列を取得します。
" /home /opt /usr ... "
- 引用した場合、
*" $a "*
- 二重括弧内の演算子は、
==
実際には完全等価ではなく、パターンマッチング演算子です。 - 私たちのモデルは次のとおりです。
- 0個以上の文字の後に
- スペース、それから
- 値
$a
、その後 - スペース、それから
- 0個以上の文字
- 二重括弧内の演算子は、
したがって、 の各値について、通常の文字列にスペースで区切られた単語として表示されることをdfArray
確認します。dsmArray
これは、配列要素にスペースを含めることができるという事実に関連しています。その後、新しい値を割り当てる必要があり、IFS
状況が乱雑になります。
私がする共通要素の配列を取得するには
typeset -i n=0
set -A common
for a in "${dfArray[@]}"; do
if [[ " ${dsmArray[*]} " == *" $a "* ]]; then
let n+=1
common[n]=$a
fi
done
echo "common"
printf "%s\n" "${common[@]}"
echo "common with index"
typeset -i i=1
while (( i <= n )); do echo "$i ${common[i]}"; ((i+=1)); done
common
/usr
...
common with index
1 /usr
2 ...