如何在 ksh 中过滤字符串数组

如何在 ksh 中过滤字符串数组

我想从“aa”数组中删除“bb”数组中定义的IP,以便IP255.0.0.0255.255.255.0将从列表中删除大批。

当我运行 ksh 代码并稍后打印数组 aa 时,我看到 IP -255.255.255.0没有被删除?

我的语法有什么问题?

   echo ${aa[*]}
   45.32.3.5 255.0.0.0 255.255.255.0 19.23.2.12


   echo ${bb[*]}
   255.0.0.0 255.255.255.0

ksh 程序:

  for run in  ${bb[*]}
  do
   for ((i=0; i<${#aa[@]}; i++)); do
   [[ ${aa[i]} == $run ]] && unset aa[i]
   done
  done

测试:

 echo ${aa[*]}
   45.32.3.5 255.255.255.0 19.23.2.12                  

笔记:255.255.255.0 应从上面的列表中删除。

答案1

我不知道为什么您的代码不适用于所提供的输入。它在我的系统上的 ksh 下运行。

但是您的原始代码有一个问题:条件部分i<${#aa[@]}很脆弱 - 因为${#aa[@]},即数组大小在每次之后递减unset- 但以下数组元素不会自动向左移动。对于你的例子

45.32.3.5 255.0.0.0 255.255.255.0 19.23.2.12

这不会产生影响 - 但它会产生影响 - 比如说:

45.32.3.5 255.0.0.0 19.23.2.12 255.255.255.0

我针对该问题改进了代码(注意循环入口之前的赋值)。我还消除了一个内部循环(使用关联数组),这将运行时间从二次改进为线性:

$ cat x.sh

输出它:

aa=(45.32.3.5 255.0.0.0 255.255.255.0 19.23.2.12)
bb=([255.0.0.0]=1 [255.255.255.0]=1)

print Size of input ${#aa[*]}
print Size of exclude list ${#bb[*]}

n=${#aa[*]}
for ((i=0; i<$n; ++i))
do
  if [[ ${bb[${aa[i]}]} ]]
  then
    print Removing element with index $i: ${aa[i]}
    unset aa[i];
  fi
  print New size of input ${#aa[*]}
done

print Resulting size of input ${#aa[*]}
print Resulting elements ${aa[*]}

for ((i=0; i<$n; ++i))
do
  print Index $i, Value 'a['$i']'=${aa[$i]}
done

它在 Fedora 17 上产生以下输出:

$ ksh x.sh
Size of input 4
Size of exclude list 2
New size of input 4
Removing element with index 1: 255.0.0.0
New size of input 3
Removing element with index 2: 255.255.255.0
New size of input 2
New size of input 2
Resulting size of input 2
Resulting elements 45.32.3.5 19.23.2.12
Index 0, Value a[0]=45.32.3.5
Index 1, Value a[1]=
Index 2, Value a[2]=
Index 3, Value a[3]=19.23.2.12

相关内容