配列から要素を完全に削除するにはどうすればよいですか?


48

unset array[0]要素を削除しますが、まだecho ${array[0]}私がnull値を取得した場合、これを行う他の方法がありますが、配列の要素に次のようなスペースが含まれている場合

array[0]='james young'
array[1]='mary'
array[2]='randy orton'

しかし、これらも仕事をするのに失敗します

array=${array[@]:1} #removed the 1st element

今、私は新しい配列を次のようにしたい

array[0]='mary'
array[1]='randy orton'

スペースは割り当て後に問題を引き起こし、実際の配列は置換のようになります。

array=(mary randy orton)

4
いいえ、スペースが問題を引き起こすのではなく、引用符がありません。
マナトワーク

回答:


68

割り当てに配列構文を使用し、変数を引用するだけです:

array=("${array[@]:1}") #removed the 1st element

コメントの質問に従って編集します。次の$@ように使用できます:

set -- "${@:2}" #removed the 1st parameter

8
最初の要素ではなく、インデックス0の要素を削除して、インデックスを再割り当てすることに注意してください。最初の要素がindice 12にあった場合、何も削除されませんが、インデックスを再割り当てして、かつてindice 12にあったものがindice 0になるようにします。今後の参照。zshkshまたはbashに反して配列がスパースではない場合、動作は異なります。
ステファンシャゼル

3
こんにちは@StephaneChazelas。「インデックス」の単数形は「インデックス」です。ご意見をありがとうございます!
スティーブンルー

3
@manatwork-再:あなたの編集-なぜ使用しないのshiftですか?
-don_crissti

1
@don_crissti、良い点。私は索引付けの違いに注目し、それ以上は考えませんでした。また、たとえば最後の3 array=("${array[@]: -3}")とを正確に保持するために、可変量のアイテムを破棄する必要がある場合の状況も念頭に置いていましたset -- "${@: -3}"。インデックスにこだわっています。
マナトワーク

1
shift $[$#-3]最後の3のために、おそらくはるかに速いためである$@
ティノ

0

これは私に考えさせられました。sed / awk / tailの問題は、行ごとであることです。最初の行を削除した後、パターンスペースからファイルに1行おきに書き込む必要があります。

  • 次のコマンドを使用して、必要な処理を数秒で実行できます。
  • これにより、ファイル全体が配列に書き込まれます。
  • 最初の行を削除してファイルに戻します。

    readarray -t aLargeFile < <(cat largefile)
    echo "${aLargeFile[@]:1}" >largefile

largefileファイルの名前に変更するだけです。


sed -i 1d largefile代わりに使用しないのはなぜですか?RAM +スワップよりも大きいファイルの場合、このさえ作品
ティノ

0

特定のインデックスの要素を削除するには、使用unsetしてから別の配列にコピーします。unsetこの場合だけは必要ありません。のでunset要素を削除しません。それだけで、アレイ内の特定のインデックスにヌル文字列を設定します。

declare -a arr=('aa' 'bb' 'cc' 'dd' 'ee')
unset 'arr[1]'
declare -a arr2=()
i=0
for element in ${arr[@]}
do
    arr2[$i]=$element
    ((++i))
done
echo ${arr[@]}
echo "1st val is ${arr[1]}, 2nd val is ${arr[2]}"
echo ${arr2[@]}
echo "1st val is ${arr2[1]}, 2nd val is ${arr2[2]}"

出力は

aa cc dd ee
1st val is , 2nd val is cc
aa cc dd ee
1st val is cc, 2nd val is dd

-1
#!/bin/bash

q=( one two three four five )

echo -e "
  (remove) { [:range:] } <- [:list:]
                | [:range:] => return list with range removed range is in the form of [:digit:]-[:digit:]
"

function remove {
  if [[ $1 =~ ([[:digit:]])(-([[:digit:]]))?   ]]; then
    from=${BASH_REMATCH[1]}
    to=${BASH_REMATCH[3]}
  else
    echo bad range
  fi;shift
  array=( ${@} )
  local start=${array[@]::${from}}
  local rest
  [ -n "$to" ] && rest=${array[@]:((${to}+1))}  || rest=${array[@]:((${from}+1))}
  echo ${start[@]} ${rest[@]}
}

q=( `remove 1 ${q[*]}` )
echo ${q[@]}
~                                                                                                                                                              
~                       

4
これは、単なるコードの塊ではなく、それがどのように機能するかを説明する何かがあれば、はるかに良いでしょう。そして、下部のチルダとは何ですか?
CVn

3
真剣に、あなたは正しいです。これはフーリガンによって書かれたように見えますが、ありがとうございます。私は本当にハンバーガーを提供する日の間でこれをこっそりすることができます。
MageProspero

qの要素にスペースが含まれている場合、これにより複数の要素に分割されます。
ウィリアムエベレット14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.