要素を削除するための代替方法
for ループと unset は、配列から要素を削除するための一般的なアプローチですが、Bash には、特定の状況でより簡潔または効率的な他の方法も用意されています。2 つの代替アプローチを探ってみましょう。
方法 1:フィルタリングされた要素を持つ新しい配列の作成
既存の配列から要素を削除する代わりに、保持したい要素のみを含む新しい配列を作成できます。このアプローチでは、要素を削除した後に配列を再インデックスする必要がありません。
/home/labex/project
ディレクトリにfilter_array.sh
という名前の新しいファイルを作成します。
#!/bin/bash
## Define our fruits array
fruits=("apple" "banana" "cherry" "orange" "apple" "grape")
## If no argument provided, default to removing "apple"
fruit_to_remove=${1:-"apple"}
echo "Original array: ${fruits[@]}"
echo "Removing: $fruit_to_remove"
## Create a new array without the matching elements
declare -a filtered_fruits
for fruit in "${fruits[@]}"; do
if [ "$fruit" != "$fruit_to_remove" ]; then
filtered_fruits+=("$fruit")
fi
done
## Print the filtered array
echo "Array after removing '$fruit_to_remove': ${filtered_fruits[@]}"
ファイルを保存し、実行可能にします。
chmod +x /home/labex/project/filter_array.sh
スクリプトを実行します。
./filter_array.sh
次のような出力が表示されるはずです。
Original array: apple banana cherry orange apple grape
Removing: apple
Array after removing 'apple': banana cherry orange grape
方法 2:配列置換パターンを使用する
Bash には、配列をフィルタリングするために使用できる強力なパラメータ展開構文が用意されています。この方法を新しいスクリプトで実装してみましょう。
/home/labex/project
ディレクトリにpattern_remove.sh
という名前のファイルを作成します。
#!/bin/bash
## Define our fruits array
fruits=("apple" "banana" "cherry" "orange" "apple" "grape")
## If no argument provided, default to removing "apple"
fruit_to_remove=${1:-"apple"}
echo "Original array: ${fruits[@]}"
echo "Removing: $fruit_to_remove"
## Create a temporary array to store valid indices
declare -a indices=()
for i in "${!fruits[@]}"; do
if [ "${fruits[$i]}" != "$fruit_to_remove" ]; then
indices+=("$i")
fi
done
## Create the filtered array using the valid indices
declare -a filtered_fruits=()
for i in "${indices[@]}"; do
filtered_fruits+=("${fruits[$i]}")
done
## Print the filtered array
echo "Array after removing '$fruit_to_remove': ${filtered_fruits[@]}"
ファイルを保存し、実行可能にします。
chmod +x /home/labex/project/pattern_remove.sh
スクリプトを実行します。
./pattern_remove.sh grape
"grape"が削除された出力が表示されるはずです。
Original array: apple banana cherry orange apple grape
Removing: grape
Array after removing 'grape': apple banana cherry orange apple
方法の比較
3 つのすべての方法を比較するサマリスクリプトを作成しましょう。/home/labex/project
ディレクトリにcompare_methods.sh
という名前のファイルを作成します。
#!/bin/bash
## Define our test array
fruits=("apple" "banana" "cherry" "orange" "apple" "grape")
fruit_to_remove=${1:-"apple"}
echo "Original array: ${fruits[@]}"
echo "Removing: $fruit_to_remove"
echo ""
## Method 1: Using for loop and unset
echo "Method 1: Using for loop and unset"
declare -a fruits_copy=("${fruits[@]}")
for ((i = ${#fruits_copy[@]} - 1; i >= 0; i--)); do
if [ "${fruits_copy[$i]}" == "$fruit_to_remove" ]; then
unset "fruits_copy[$i]"
fi
done
fruits_copy=("${fruits_copy[@]}")
echo "Result: ${fruits_copy[@]}"
echo ""
## Method 2: Creating a new filtered array
echo "Method 2: Creating a new filtered array"
declare -a filtered_fruits=()
for fruit in "${fruits[@]}"; do
if [ "$fruit" != "$fruit_to_remove" ]; then
filtered_fruits+=("$fruit")
fi
done
echo "Result: ${filtered_fruits[@]}"
echo ""
## Method 3: Using array indices
echo "Method 3: Using array indices"
declare -a indices_filtered=()
for i in "${!fruits[@]}"; do
if [ "${fruits[$i]}" != "$fruit_to_remove" ]; then
indices_filtered+=("${fruits[$i]}")
fi
done
echo "Result: ${indices_filtered[@]}"
ファイルを保存し、実行可能にします。
chmod +x /home/labex/project/compare_methods.sh
削除するさまざまな果物でスクリプトを実行します。
./compare_methods.sh banana
3 つのすべての方法の比較が表示されるはずです。
Original array: apple banana cherry orange apple grape
Removing: banana
Method 1: Using for loop and unset
Result: apple cherry orange apple grape
Method 2: Creating a new filtered array
Result: apple cherry orange apple grape
Method 3: Using array indices
Result: apple cherry orange apple grape
3 つのすべての方法は同じ目標を達成しますが、それぞれに利点があります。
- 方法 1(for ループと unset を使用)は、元の配列をインプレースで変更します
- 方法 2(新しい配列を作成する)は、多くの場合、より明確であり、インデックスシフトの問題を回避します
- 方法 3(配列インデックスを使用する)は、元の配列を保持する必要がある場合に役立ちます
特定のユースケースとコーディングスタイルに最適な方法を選択してください。