对字符串数组中的唯一条目进行排序和计数 [英] Sort and count unique entries in an array of strings

查看:129
本文介绍了对字符串数组中的唯一条目进行排序和计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要做的是从etc/group获取用户列表,然后对其进行排序,然后计算唯一条目.

What I need to do is to get the list of users from etc/group, then sort it and then count unique entries.

现在我只设法获得了用户名.但是我怀疑这是错误的.

Right now I only managed to get the usernames. But I suspect that it is wrong.

#!/bin/bash
usernames=();

while IFS=: read -r Groups Tmp1 Tmp2 Username
do
  if [ $Username!="" ];
  then
    usernames+=($Username);
  fi;
done < /etc/group

然后我也尝试对其进行排序,但输出为非常很奇怪:

Then I also tried to sort it, but the output is VERY weird:

排序:

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经验为零,而且绝对无法正常工作.

I have zero bash experience and absolutely can't get it to work.

我需要的最基本的解决方案是仅从/etc/group中获得唯一名称的用户名排序列表,并打印每个用户的表示数量.

What I need the most basic solution to get the sort list of usernames from /etc/group with only the unique entries and print the amount of repitions of each.

例如,如果我有此/etc/group文件:

For ex if I have this /etc/group file:

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

推荐答案

每个用户名"字段实际上是一个可选的用逗号分隔的空用户名列表.要分隔用户名,您需要在逗号之间分割条目.

Each 'username' field is actually an optionally empty comma-separated list of user names. To get the user names separated, you'll need to split the entries on commas.

如果我从您的循环开始,我可能会使用:

If I started from your loop, I'd probably use:

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:

This bypasses the intermediate usernames array. If you really want that, then keep your original loop and pipe the input to sort through the tr command before sort:

IFS=$'\n' sorted=($(tr ',' '\n' <<<"${usernames[*]}" | sort -u))

这将生成一个数组sorted,其中包含按排序顺序排列的唯一名称列表.

This generates an array, sorted, containing the list of unique names in sorted order.

如果您只想计算唯一名称,那么我可能会在awk中做全部事情.确实,我很想使用awk而不是while循环.

If all you want is a count of the unique names, I'd probably do the whole thing in awk, though. Indeed, I'd be tempted to use awk instead of the while loop.

如果要计算每个唯一名称的出现次数,请使用sort | uniq -c代替sort -u.统计信息中的选项和变式比较多-关键是您需要在逗号上分割/etc/group文件的最后一个字段.如果出于某种原因您在该列表中有空格,则可能也必须摆脱这些空格. tr ', ' '\n'会做到这一点.

If you want a count of the occurrences of each unique name, then instead of sort -u you'd use sort | uniq -c. The options and variants on the statistics are legion — the key point is that you need to split the last field of the /etc/group file on the commas. If you have spaces in that list for some reason, you may have to get rid of those, too. tr ', ' '\n' would do that.

使用awk,您可以执行以下操作:

Using awk, you could do:

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数组中的条目.在我的Mac上,它产生了:

It splits the fourth field into the array a, then counts the occurrences of each name in the count array. At the end, it prints the entries from the count array. On my Mac, it yielded:

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

您可以根据需要进一步对其进行排序.

You can further sort that as required.

这篇关于对字符串数组中的唯一条目进行排序和计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆