I trying to modify around 1000 users by removing the "_" from the comment and replacing it with a space. Here is an example about how one of the user would look:
af1571:x:3571:100:aleja _ fischer:/home/af1571:/bin/bash
I have written a script in bash but it is not working, i think is not going thorough the for loop also, i dont think my usermod command is good as well.
here is what i have so far:
#!usr/bin/bash
FILENAME="/etc/passwd"
while IFS=: read -r username password userid groupid comment homedir cmdshell
do
for i in "{$userid > 1000 && $userid < 2000}"
do
usermod $username -c $comment sed "s/_/ /g"
done
done< $FILENAME
CodePudding user response:
If you have GNU awk gawk
installed and the inplace
extension is available there's a fairly easy way to achieve this w/o any looping ...
gawk -i inplace -v inplace::suffix=.bak 'BEGIN{FS=OFS=":"}{if($3>=1000 && $3<2000){gsub(/_/, " ",$5)}; print }' /etc/passwd
If you have only a posix-awk available, this would do it:
awk 'BEGIN{FS=OFS=":"}{if($3>=1000 && $3<2000){gsub(/_/, " ",$5)}; print }' /etc/passwd > ~/passwd.new && mv ~/passwd.new /etc/passwd
Given the importance of the file you may want to experiment on a copy of it first to confirm that it works for you ;)
CodePudding user response:
Try this Shellcheck-clean code:
#! /bin/bash -p
getent passwd \
| while IFS=: read -r username _ userid _ comment _ _; do
(( userid > 1000 )) || continue
(( userid < 2000 )) || continue
[[ $comment == *_* ]] || continue
usermod -c "${comment//_/ }" "$username"
done
- On modern systems
/etc/passwd
may not include all of the valid users. For instance, users may be configured via LDAP. The code usesgetent passwd
to get the full list of users. If you really only want to modify users listed in/etc/passwd
, replacegetent passwd | while ... done
withwhile ... done </etc/passwd
. - The
_
characters in theread
arguments cause the corresponding input fields to be discarded. There's no point putting them in variables because they aren't used. See BashFAQ/001 (How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?). [[ $comment == *_* ]] || continue
causes users whose comments don't contain underscores to be skipped. They don't need to be modified."${comment//_/ }"
expands to the$comment
string with all underscores replaced by spaces. See Parameter expansion [Bash Hackers Wiki].