如何在Linux bash中为每个用户在一行中显示组下的用户

Posted

技术标签:

【中文标题】如何在Linux bash中为每个用户在一行中显示组下的用户【英文标题】:how to display users under a group in a line for each user in Linux bash 【发布时间】:2021-12-06 01:42:07 【问题描述】:

目前,当我在我创建的访客组上运行 grep 命令时

grep visitors:x:1011: /etc/group

这是上述命令的示例结果,实际结果太长了。

visitors:x:1011:ellipsiscoterie,magnetcommonest,wizardmeans,beakskeletal,lemonwellmade,ralphpaperclips etc..

我如何显示上面的结果,如下所示(没有visitors:x:1101 和逗号分隔),因为我很难这样做。

ellipsiscoterie
magnetcommonest
wizardmeans
beakskeletal
lemonwellmade
ralphpaperclips

【问题讨论】:

【参考方案1】:

我建议使用sed 而不是grep

sed -n -e 's/^visitors\:x\:1011\://p' /etc/group | tr ',' '\n'

UPD:sed 部分的详细解释是here。 tr 例子你可以找到here

【讨论】:

【参考方案2】:

一种选择是使用awk

awk -F: '$1 == "visitors" 
    size = split($4, users, ",");
    for(i=1; i<=size; ++i) print users[i];
    exit ' /etc/group
-F: - 使用 : 作为字段分隔符 $1 == "visitors" - 如果第一个字段匹配 visitors 执行以下语句(在 ... 内) size = split($4, users, ","); - 拆分 , 上的第 4 个字段并将结果存储在数组 users 中。返回users 中的元素数并将其放入sizefor 循环 - 循环 users 中的所有元素并将它们打印出来。 exit - 终止 awk - 无需继续阅读文件的其余部分。

【讨论】:

【参考方案3】:

使用awk,您可以将字段设置为使用-F:分隔的冒号,并检查字符串是否以visitors:x:1011:开头

由于逗号分隔的值似乎总是在末尾,因此将最后一个字段 $NF 拆分为逗号并循环拆分的值。

awk -F: '
/^visitors:x:1011:/ 
  count=split($NF, ary, ",");
  for(i=1; i<=count; i++) print ary[i];
' /etc/group

【讨论】:

【参考方案4】:

查询组和用户的一个好方法是使用getent 命令,因为它也适用于 ldap 系统。

$ getent group visitors | cut -d: -f4 | tr ',' '\n'

在标准系统上,这将始终有效,因为用户名和组名不能包含 -character 或 -character。 (如果您有非标准的 Linux 或 Unix 系统,请参阅 man useraddman groupadd 以检查用户名和组名规则)

如果您想使用 awk 而不是这个小管道,那么一个优雅但神秘的版本将是:

$ getent group visitors | awk -F: 'FS=",";OFS=ORS;$0=$4;$1=$11'

【讨论】:

我希望我在写答案时想到了getent。虽然我仍然会使用awk 来解析输出,但getent 似乎仍然是合适的工具。 @TedLyngmo 我也是 awk 的忠实粉丝,但是不应低估管道的效率以及那些可以很好地完成一件事的优化原子工具(剪切、粘贴、tr、连接、 ...)。对于这样的任务,awk 有点像大锤 :-) 对。这不是工具。这是我想避免的额外过程和管道,但实际上,它可能并不重要。我真的喜欢你的awk 版本!希望我能再投票一次。【参考方案5】:

使用您展示的示例,请尝试关注awk 程序。

awk -F':' '/^visitors:x:1011/ && NF==4gsub(/,/,ORS,$4);print $4' /etc/group

如果条目 visitors:x:1011 在您的文件中仅出现一次,请尝试以下操作:

awk -F':' '/^visitors:x:1011/ && NF==4gsub(/,/,ORS,$4);print $4;exit' /etc/group

解释: 简单的解释是,将所有行的字段分隔符设为:。然后在主程序中,检查条件是否行从visitors:x:1011 开始并且字段数为4,然后在第4个字段中用新行(ORS)全局替换逗号并打印。



OR 如果与 visitors:x:1011 的行出现一次且第 4 个字段为 NULL(表示不存在条目,这在某些情况下很明显)并且您想要打印消息然后尝试以下操作:

awk -F':' '/^visitors:x:1011/ &amp;&amp; NF==4if($4=="")print "NO entry found in /etc/group" elsegsub(/,/,ORS,$4);print $4;exit' /etc/group

【讨论】:

【参考方案6】:

如果grep visitors:x:1011: /etc/group的结果是文本行:

visitors:x:1011:ellipsiscoterie,magnetcommonest,wizardmeans,beakskeletal,lemonwellmade,ralphpaperclips

你可以试试这个awk:

awk '/^visitors:/ sub(/([^:]+:)+/,"");gsub(/,/, ORS) 1' file
ellipsiscoterie
magnetcommonest
wizardmeans
beakskeletal
lemonwellmade
ralphpaperclips
初始正则表达式:如果该行开头匹配visitors:,请执行以下操作。 操作:使用sub() 消除直到最后一个: 的所有字符,然后使用gsub() 将所有逗号替换为默认值ORS

【讨论】:

以上是关于如何在Linux bash中为每个用户在一行中显示组下的用户的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中为整个应用程序(如每个屏幕)在屏幕底部显示自定义视图

如何在recyclerview(FirebaseRecyclerOptions)中为特定用户显示所有孩子

如何在 MySQL 中为每个 ID 只选择一行?

如何在 MySQL 中为每个唯一列值选择两条记录作为一行?

转:linux下shell显示-bash-4.1#不显示路径解决方法

一个bash脚本,用于使用bash脚本连接字符串并在同一文件中编辑一行