KSHで2つの配列を比較し、違いを印刷します。

KSHで2つの配列を比較し、違いを印刷します。

私はそれに慣れておらず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 "* ]]

  1. " ${dsmArray[*]} "
    • 引用した場合、"${ary[*]}"結果は最初の文字に関連付けられた配列の個々の要素で構成される単一の文字列です。$IFS
    • デフォルトは$IFS3文字です:スペース、タブ、改行
    • 先頭と末尾の引用符を使用して文字列を取得します。" /home /opt /usr ... "
  2. *" $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  ...

関連情報