kshで文字列配列をフィルタリングする方法

kshで文字列配列をフィルタリングする方法

「aa」配列から「bb」配列で定義されたIPを削除する255.0.0.0そして255.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

私はこの問題のコードを改善しました(ループエントリの前の割り当てに注意してください)。また、内部ループ(連想配列を使用)を削除して、実行時間を2次から線形に改善しました。

$ 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

おすすめ記事