我编写了一个 bash 程序,它扫描 /etc/passwd 并打印出目录中的所有用户名,但是我需要该程序仅打印长度在 5 到 10 个字符之间的用户名。我需要改变它。
#!/bin/bash
MAXLENGTH=$(cut -d: -f1 < /etc/passwd | wc -L)
MINLENGTH=$MAXLENGTH
SMALLESTNAME=""
for NAME in $(cut -d: -f1 < /etc/passwd)
do
if [ ${#NAME} -eq $MAXLENGTH ]
then
echo "The Longest UserName In The System
Is:" $NAME
echo " Its Length Is" $MAXLENGTH
elif [ ${#NAME} -lt $MINLENGTH ]
then
MINLENGTH=${#NAME}
SMALLESTNAME=$NAME
fi
done
echo
echo "The Smallest UserName In The System Is:"
$SMALLESTNAME
echo "Its Length is:" $MINLENGTH
答案1
getent passwd | awk -F : 'length($1) >= 5 && length($1) <= 10 { print $1 }'
这将打印长度在 5 到 10 个字符之间(含)的用户名。
对于最短和最长的名称:
getent passwd |
awk -F : 's == "" || length($1) < length(s) { s = $1 }
l == "" || length($1) > length(l) { l = $1 }
END { printf("shortest: %s (%d chars)\n", s, length(s))
printf("longest: %s (%d chars)\n", l, length(l)) }'
只需一次通过密码数据库即可完成这两件事(作为一个完整的bash
脚本,尽管/bin/sh
应该已经足够了,因为该脚本不使用任何bash
特定的内容,任何shell 将能够运行它):
#!/bin/bash
getent passwd |
awk -F : 'length($1) >= 5 && length($1) <= 10 { print $1 }
s == "" || length($1) < length(s) { s = $1 }
l == "" || length($1) > length(l) { l = $1 }
END { printf("shortest: %s (%d chars)\n", s, length(s))
printf("longest: %s (%d chars)\n", l, length(l)) }'
答案2
不切实际但有点令人着迷:bash扩展文件模式:
shopt -s extglob
getent passwd |
cut -d: -f1 |
while IFS= read -r name; do
[[ $name == ?????@(|?|??|???|????|?????) ]] && echo "$name"
done
答案3
这是你的家庭作业解决方案:
#!/bin/bash
for NAME in $(cut -d: -f1 < /etc/passwd)
do
if [[ ${#NAME} -gt 10 || ${#NAME} -lt 5 ]]
then
continue
else
echo "Username in the system is: $NAME"
echo "Its length Is ${#NAME}"
fi
done
不客气。
答案4
想要更多一点的多样性,cut
并且grep
:
getent passwd | cut -d: -f1 | grep -Ex '.{5,10}'
这会检索 passwd 条目,删除第一个字段(用户名),然后要求 grep 提供跨越整行 ( -x
) 的扩展正则表达式匹配,其中包含 5 到 10 个任意字符 ( .
)。