KSH에서 두 배열을 비교하고 차이점을 인쇄합니다.

KSH에서 두 배열을 비교하고 차이점을 인쇄합니다.

나는 그것에 익숙하지 않으며 KSH(실제로는 방금 사용하기 시작했습니다) 본질적으로 두 개의 저장된 배열을 비교한 다음 차이점을 출력하는 스크립트를 만드는 데 문제가 있습니다.

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

두 배열은 다음과 같습니다.

/
/usr
/var
/tmp
...

DSM 배열:

/home
/opt
/usr
...

현재 스크립트를 실행하면 다음 오류가 발생합니다.

./checkBackup.sh[22]:  / != /home : syntax error

내가 뭘 잘못했나요? 아마도 간단한 일이라고 확신합니다.

감사해요!

답변1

문자열 값에 대해 산술 평등을 수행하려고 하기 때문에 오류가 발생합니다.

요소가 dfArray있는지 확인하는 두 가지 방법은 다음과 같습니다.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  ...

관련 정보