Bash: Как мне усечь массив? - PullRequest
2 голосов
/ 01 декабря 2009

Я бы хотел изменить значение массива и был бы признателен за любую помощь.

Я получил такой массив:

users=(root isometric akau)

(На самом деле это список текущих пользователей), который я хотел бы проверить, существует ли пользователь, а если нет, то удалить человека из массива. Я попытался поэкспериментировать с этим, поместив его в цикл for и оценив его:

for i in ${users[@]}; do
  eval "users=($([ -z $(grep \"^\$i\" /etc/shadow) ] && sed \"s/\$i//g\"))"
done

echo $users

Я думал о том, чтобы поиграть с этим еще немного, но подумал, что может быть слишком сложно (не уверен, что смогу поместить команду в массив) У кого-нибудь есть идеи, как это сделать?

Edit:

Как я ввел переменную массива unset number:

cnt=0
for i in ${users[@]}; do
  [ -z "$(grep "^$i" /etc/shadow)" ] && unset users[cnt] || ((cnt++))
done

Edit2:

На самом деле Деннис даже лучше.

Ответы [ 4 ]

5 голосов
/ 01 декабря 2009

Возможно, вам не нужен цикл for. Попробуйте это:

users=(root isometric akau)
list="${users[@]/%/|}"      # convert array to list, add pipe char after each user
# strip the spaces from the list and look for usernames between the beg. of the line
# and the end of the word, make an array out of the result
users=($(grep -Eo "^(${list// })\>" /etc/shadow))

Раскрытый grep будет выглядеть так:

grep -Eo "^(root|isometric|akau|)\>" /etc/shadow
4 голосов
/ 01 декабря 2009

Так что, если у вас есть ...

$ users=(root isometric akau)
$ echo ${users[*]}
root isometric akau

Все, что вам нужно сделать, это сказать:

$ unset users[1]

А потом ...

$ echo ${users[*]}
root akau
$ 
0 голосов
/ 01 декабря 2009
users=(root nobody akau)
declare -a shadowusers
declare -a notinshadow
i=0
while IFS=":" read -r user b c d e f g h
do
    shadowusers[$i]=$user
    i=$((i+1))
done < "/etc/shadow"
for u in ${users[@]}
do
    found=0
    for s in ${shadowusers[@]}
    do
           case "$u" in
               "$s") found=1;;
           esac   
    done
    [ "$found" -eq 0 ] && notinshadow[$j]=$u
    j=$((j+1)) 
done 
echo ${notinshadow[@]}
0 голосов
/ 01 декабря 2009

Если вы хотите удалить jane из users:

users=(john joe mary jane liz root foobar)

for ((i = 0; i < ${#users[@]}; ++i)); do
    [[ ${users[i]} == jane ]] && break
done

users=(${users[@]:0:i} ${users[@]:i+1})

echo "${users[@]}" #=> john joe mary liz root foobar

Общий принцип состоит в том, что в bash нет среза массива (очевидно); Вы должны воссоздать массив без исключенных элементов.

Тем не менее, существует множество способов сделать то, что вы ищете, в цикле for (in).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...