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
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 ;)
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
/etc/passwd
may not include all of the valid users. For instance, users may be configured via LDAP. The code uses getent passwd
to get the full list of users. If you really only want to modify users listed in /etc/passwd
, replace getent passwd | while ... done
getent passwd | while ... done
with while ... done </etc/passwd
. _
characters in the read
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
[[ $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] .Using getent getent passwd {1001..1999}
list users between 1000 and 2000
Calling cmd usermod
from awk after modifying comment $5
for user $1
using delimiter :
getent passwd {1001..1999}|awk -F: '{gsub(/_/," ",$5);print|"usermod "$1" -c \""$5"\""}'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.