Reputation: 2298
I'd like to change the value of an array and would appreciate any help.
I got an array like this:
users=(root isometric akau)
(This is actually a list of current users) that I'd like to be able to test if the user exists and if they do not, then to remove the person from the array. I've tried experiment with this by putting it in a for loop and evaluating it:
for i in ${users[@]}; do
eval "users=($([ -z $(grep \"^\$i\" /etc/shadow) ] && sed \"s/\$i//g\"))"
done
echo $users
I thought about playing with this some more but I thought I might be getting too complicated (I'm not sure I can put a command in an array). Anyone have an idea on how to do this?
Edit:
How I entered the array variable unset number:
cnt=0
for i in ${users[@]}; do
[ -z "$(grep "^$i" /etc/shadow)" ] && unset users[cnt] || ((cnt++))
done
Edit2:
Actually Dennis's is even better.
Upvotes: 2
Views: 3402
Reputation: 360405
You may not need a for
loop. Try this:
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))
The grep
, unraveled, would look like this:
grep -Eo "^(root|isometric|akau|)\>" /etc/shadow
Upvotes: 5
Reputation: 342759
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[@]}
Upvotes: 0
Reputation: 146171
So if you have...
$ users=(root isometric akau)
$ echo ${users[*]}
root isometric akau
All you need to do is, say:
$ unset users[1]
And then...
$ echo ${users[*]}
root akau
$
Upvotes: 4
Reputation: 10815
If you want to remove jane
from 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
The general principle is that there is no array slice in bash (obviously); you have to recreate the array without the excluded element(s).
That said, there are numerous ways to do what your are looking for in a for(in) loop.
Upvotes: 0