我正在尝试编写一个 shell 脚本,用于打印登录到计算机的用户的全名。finger 命令给了我一个用户列表,但有很多重复项。如何循环浏览并仅打印出唯一的内容?
编辑:
这是手指给我的格式:
xxxx XX of group XXX pts/59 1:00 Feb 13 16:38
xxxx XX of group XXX pts/71 1:11 Feb 13 16:27
xxxx XX of group XXX pts/105 1d Feb 12 15:22
xxxx YY of group YYY pts/102 2:19 Feb 13 14:13
xxxx ZZ of group ZZZ pts/42 2d Feb 7 12:11
我正在尝试提取全名(即第 2 列中"组"之前的任何内容),所以我会将 awk 与手指一起使用。
你想要的在 shell 脚本中实际上相当困难,例如,这是我的完整输出 finger(1)
:
Login Name TTY Idle Login Time Office Phone
martin Martin Tournoij *v0 1d Wed 14:11
martin Martin Tournoij pts/2 22 Wed 15:37
martin Martin Tournoij pts/5 41 Thu 23:16
martin Martin Tournoij pts/7 31 Thu 23:24
martin Martin Tournoij pts/8 Thu 23:29
你想要全名,但这可能包含 1 个空格(根据我的例子),或者它可能只是"Teller"(没有空格),或者可能是"詹姆斯 T. 柯克船长"(3 个空格)。因此,您不能只使用空格作为分隔符。您可以使用标题中"TTY"的字符位置作为指示器,但恕我直言,这不是很优雅(尤其是使用 shell 脚本)。
因此,我的解决方案略有不同,我们只从finger(1)
那里获得用户名,然后我们从/etc/passwd
#!/bin/sh
prev=""
for u in $(finger | tail +2 | cut -w -f1 | sort); do
[ "$u" = "$prev" ] && continue
echo "$u $(grep "^$u" /etc/passwd | cut -d: -f5)"
prev="$u"
done
这给了我用户名和登录名:
martin Martin Tournoij
显然,您也可以只打印真实姓名(不打印$u
)。
sort
和uniq
BinUtils 命令可用于删除重复项。
finger | sort -u
这将删除所有重复的行,但由于 finger 命令的冗长程度,您仍然会看到类似的行。如果您只想要用户名列表,则可以进一步过滤掉它以使其非常具体。
finger | cut -d ' ' -f1 | sort -u
现在,您可以更进一步,删除finger
命令打印出来的"标题/标签"行。
finger | cut -d ' ' -f1 | sort -u | grep -iv login
希望这有帮助。
其他可能的解决方案:
finger | tail -n +2 | awk '{ print $1 }' | sort | uniq
-
tail -n +2
省略第一行。 -
awk '{ print $1 }'
提取第一列。 -
sort
准备uniq
输入。 -
uniq
删除重复项。
如果要迭代使用:
for user in $(finger | tail -n +2 | awk '{ print $1 }' | sort | uniq)
do
echo "$user"
done
这能更简单吗?无需担心空格或任何其他特殊字符!
finger -l | awk '/^Login/'
编辑:删除of group
后的内容
finger -l | awk '/^Login/' | sed 's/of group.*//g'
输出:
Login: xx Name: XX
Login: yy Name: YY
Login: zz Name: ZZ