我需要做的是从etc/group
获取用户列表,然后对其进行排序,然后计算唯一条目。
现在我只设法获取用户名。但我怀疑这是错误的。
#!/bin/bash
usernames=();
while IFS=: read -r Groups Tmp1 Tmp2 Username
do
if [ $Username!="" ];
then
usernames+=($Username);
fi;
done < /etc/group
然后我也尝试对它进行排序,但输出非常很奇怪:
排序:
IFS=$'\n' sorted=($(sort <<<"${usernames[*]}"))
unset IFS
输出:
echo ${usernames[@]}
echo ""
echo ${sorted[@]}
结果:
root root root root root root _teamsserver root root _taskgated root root,_jabber,_postfix,_cyrus,_calendar,_dovecot _calendar,_jabber,_postfix _devicemgr,_teamsserver _eppc root _teamsserver _devicemgr _softwareupdate _locationd _teamsserver _devicemgr,_calendar,_teamsserver,_xserverdocs _teamsserver,_devicemgr _warmd
_calendar,_jabber,_postfix _devicemgr _devicemgr,_calendar,_teamsserver,_xserverdocs _devicemgr,_teamsserver _eppc _locationd _softwareupdate _taskgated _teamsserver _teamsserver _teamsserver _teamsserver,_devicemgr _warmd root root root root root root root root root root root,_jabber,_postfix,_cyrus,_calendar,_dovecot
我没有bash经验,绝对无法让它发挥作用。
我需要最基本的解决方案来从/ etc / group获取用户名的排序列表,只包含唯一的条目并打印每个用户的重复数量。
对于ex,如果我有这个/etc/group
文件:
nobody:*:-2:
nogroup:*:-1:
wheel:*:0:root
daemon:*:1:root
kmem:*:2:root
sys:*:3:root
tty:*:4:root
operator:*:5:root
mail:*:6:_teamsserver
我想得到这个:
root 6
_teamsserver 1
答案 0 :(得分:3)
每个用户名&#39;字段实际上是一个可选的空逗号分隔的用户名列表。要将用户名分开,您需要在逗号上拆分条目。
如果我从你的循环开始,我可能会使用:
sorted=($(while IFS=: read -r Groups Tmp1 Tmp2 Usernames
do
if [ -n "$Usernames" ];
then
echo "$Usernames"
fi
done < /etc/group |
tr ',' '\n' |
sort -u
))
echo "${sorted[@]}"
这会绕过中间usernames
数组。如果您真的想要这样,那么保留原始循环并通过sort
之前的tr
命令将输入传递给sort
:
IFS=$'\n' sorted=($(tr ',' '\n' <<<"${usernames[*]}" | sort -u))
这将生成一个数组sorted
,其中包含按排序顺序排列的唯一名称列表。
如果您想要的只是一个唯一名称的计数,我可能会在awk
中完成整个事情。实际上,我很想使用awk
代替while
循环。
如果您想要计算每个唯一名称的出现次数,那么您可以使用sort -u
代替sort | uniq -c
而不是/etc/group
。统计信息的选项和变体很多 - 关键是您需要在逗号上拆分tr ', ' '\n'
文件的最后一个字段。如果由于某种原因你在该列表中有空格,你可能也必须摆脱它们。 awk
会这样做。
使用awk -F: '{ n = split($4, a, ","); for (u = 1; u <= n; u++) count[a[u]]++i }
END { for (u in count) print u, count[u] }' /etc/group
,您可以:
a
它将第四个字段拆分为数组count
,然后计算count
数组中每个名称的出现次数。最后,它打印root 11
_warmd 1
_locationd 1
_jabber 2
_taskgated 1
_postfix 2
_devicemgr 4
_calendar 3
_cyrus 1
_teamsserver 6
_dovecot 1
_xserverdocs 1
_eppc 1
_softwareupdate 1
数组中的条目。在我的Mac上,它产生了:
defmodule Elemental.TxChat.Room do
use Elemental.TxChat.Web, :model
schema "rooms" do
field :name, :string
# Foreign key indicating which user created this room
# One user can create any number of rooms
belongs_to :created_by, Elemental.TxChat.User
field :created_from_app, :integer
many_to_many :members, Elemental.TxChat.User, join_through: "rooms_users"
timestamps()
end
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name, :created_by, :created_from_app])
|> validate_required([:name, :created_by, :created_from_app])
end
end
您可以根据需要进一步对其进行排序。
答案 1 :(得分:2)
你可以尝试类似的东西:
ngSubmitFunction()
awk -F ':' '{ if(length($4)) { gsub(",", "\n", $4); print $4 } }' /etc/group | \
sort | uniq -c
命令获取所有非空的第4个字段(':'作为分隔符)并将',替换为'\ n'以防一个组有多个用户。
然后我们对独特的外观进行排序和计数。
编辑:
没有awk
:
awk
答案 2 :(得分:1)
cut -d: -f4 /etc/group | tr , '\n' | grep '.' | \
sort | uniq -c | join -a 1 -o '1.2,1.1' - /dev/null
或者:
cut -d: -f4 /etc/group | tr , '\n' | grep '.' | \
sort | uniq -c | awk '{ print $2 " " $1 }'
工作原理:
cut
out field #4 。tr
将逗号更改为换行符。grep
删除空行。sort
,计算uniq
ue行,使用OP的规格进行打印。答案 3 :(得分:0)
略微修改的示例输入,包括,
分隔名称
$ cat abc.txt
nobody:*:-2:
nogroup:*:-1:
wheel:*:0:root
daemon:*:1:root
kmem:*:2:root,test
sys:*:3:root
tty:*:4:root,t1,test
operator:*:5:root
mail:*:6:_teamsserver
$ perl -F: -le 'foreach (split /,/,$F[3]){$h{$_}++ if /./} END{foreach (keys %h){print "$_ $h{$_}"}}' abc.txt
t1 1
_teamsserver 1
root 6
test 2
-F:
在:
上拆分输入行并保存到@F
数组foreach (split /,/,$F[3])
在,
$h{$_}++ if /./
如果非空END{foreach (keys %h){print "$_ $h{$_}"}}
以所需格式打印哈希信息