我不太熟悉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
这两个数组可能如下所示: dfArray:
/
/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 "* ]]
" ${dsmArray[*]} "
- 当引用时,
"${ary[*]}"
结果是由数组的各个元素组成的单个字符串,该数组的各个元素连接在第一个字符上$IFS
- 默认为
$IFS
3 个字符:空格、制表符、换行符 - 使用前导引号和尾随引号,我们得到字符串
" /home /opt /usr ... "
- 当引用时,
*" $a "*
- 双括号内的
==
运算符实际上是模式匹配运算符,而不是严格相等 - 我们的模式是:
- 零个或多个字符,后跟
- 一个空格,然后是
- 的值
$a
,然后是 - 一个空格,然后是
- 零个或多个字符
- 双括号内的
因此,对于 的每个值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 ...