【问题标题】:How to print linux group names on multiple line instead of single line output如何在多行而不是单行输出上打印 linux 组名
【发布时间】:2016-04-18 09:23:26
【问题描述】:

我尝试过 getent、组命令、id -Gn $user 和一些 sed 组合,但我认为我无法实现,因此联系了其他程序员。
我希望能够打印这个:groups abc123
输出 abc123 : devops 构建测试设计

预期输出
组:
- 开发运维
- 构建
- 测试
- 设计

【问题讨论】:

  • 你可以从那里开始:groups abc123 | sed 's/ /\n - /g' 然后尝试改进
  • 如果你的 shell 是 bash(或支持数组),你可以做一些简单的事情,比如 arr=($(groups)); printf "%s\n" ${arr[@]}。如果你想要领先的'- ',那么你可以做arr=($(groups)); printf -- "- %s\n" ${arr[@]}
  • 感谢@Sergius 部分工作,但至少让我的 sed 正确 :)
  • 谢谢@DavidC.Rankin

标签: linux unix sed yaml


【解决方案1】:

使用bash:

for i in `groups`; do echo $i; done

使用tr:

groups | tr \  \\n

【讨论】:

  • 谢谢@bibi,我学到了一些新东西。我以前从未尝试过 tr 命令。这也有效 - 但我们得到的输出没有组名前面的连字符,但我玩了一下 tr 并想通了。
  • 这仅适用于名称中没有空格的组!
【解决方案2】:

据我所知,您正在尝试将用户组转换为 yaml 数组,尝试使用:

echo "groups:" ; for i in $(id -Gn myuser);do echo "  - $i" ;done

groups:
  - users
  - lp
  - vboxusers
  - kvm

你也可以使用:

echo "groups: [ $(groups myuser | sed -e 's/.\+\s\+:\s\+\(.\+\)/\1/g' -e 's/\(\s\+\)/, /g') ]"

groups: [ myuser, lp, vboxusers, kvm ]

【讨论】:

  • 是的,正确 :) 谢谢你,我会一一尝试所有建议,看看哪个最适合我的脚本
  • 这仅在组名中没有空格时有效。
【解决方案3】:

回应@Chris 的comment

这仅适用于名称中没有空格的组!

我应该提到@c4f4t0r 接受的解决方案和@bibi 的解决方案在大多数情况下都可以工作。我正在运行 Cygwin,等式的 Windows 部分可能是我更经常遇到这个问题的原因。不过,在普通 Linux 中可以使用非标准字符创建一个组(我认为),所以我将给出带有空格的组名的解决方案。空间总是让生活充满乐趣!

我将快速举一个空格导致问题的示例。要查看带空格的组名,我们查看id 的整个输出

$ id
uid=1(me) gid=545(Users) 
groups=545(Users),66049(CONSOLE LOGON),11(Authenticated Users),
4095(CurrentSession),66048(LOCAL)

(注意:我确实在 StackOverflow 上使输出更令人赏心悦目。)

由此,我们看到群组是{'Users', 'CONSOLE LOGON', 'Authenticated Users', 'CurrentSession', 'LOCAL'}

在这种情况下,我们可以看到accepted solution 的问题。

$ echo "groups:" ; for i in $(id -Gn);do echo "  - $i" ;done
    groups:
      - Users
      - CONSOLE
      - LOGON
      - Authenticated
      - Users
      - CurrentSession
      - LOCAL

几个小组的名字被分开了。为了得到我们想要的输出,我们需要使用 id 命令,它带有一个--zero (-z) 标志。有关传递给id 的所有标志的更多详细信息,请参阅here

$ man id | grep -A 1 "\-\-zero"
       -z, --zero
              delimit entries with NUL characters, not whitespace;

我们的方法需要与上面给出的方法有些不同,但遵循许多相同的原则:

$ echo "groups:"; printf "%s" "  - "; id -Gnz | \
awk 'BEGIN{FS="\0"; OFS="\n  - "}{NF--; print}'
groups:
  - Users
  - CONSOLE LOGON
  - Authenticated Users
  - CurrentSession
  - LOCAL

我们有一个稍微复杂的awk 的原因是总是有一个尾随NUL,在这种情况下我们不想要它。 \ 允许我使用相同的命令继续到下一行,使事情更容易阅读。该命令相当于:

$ echo "groups:"; printf "%s" "  - "; id -Gnz | awk 'BEGIN{FS="\0"; OFS="\n  - "}{NF--; print}'

【讨论】:

  • id 在 macos 上没有 -z 标志
  • 您可以在 MacOS 上看到哪些标志?试试man id 找出答案。
  • 我不在 MacOS 上,但我也得到了 no -z 标志: -a 忽略,为了与其他版本兼容 -Z,--context 仅打印当前用户的安全上下文 -g , --group 仅打印有效组 ID -G, --groups 打印所有组 ID -n, --name 打印名称而不是数字,对于 -ugG -r, --real 打印真实 ID 而不是有效ID,带-ugG -u, --user 只打印有效用户ID --help 显示此帮助并退出 --version 输出版本信息并退出
  • 感谢@bibi 和@Tim_Edwards 提供的信息。似乎没有单独的空标志时要做的事情可能是解析id的输出,隔离groups=行,然后匹配[0-9]+[(]之类的东西( [^)(]+ ) [)] 其中分组括号采用非代码字体以进行强调。 (扩展正则表达式)
  • 这里是 non-fully-tested肯定不稳健 第一次尝试针对 no-separate-on-null 情况的代码,专门针对@bibi 和@Tim_Edwards :echo "groups:"; id | sed 's#^.*groups.\(.*\)$#\1#g' | tr ',' '\n' | sed 's#^[0-9]\+[(]\([^)(]\+\)[)]# - \1#g'(这里我们在sed 中有Normal REGEX)
【解决方案4】:

对于处理空格的简洁解决方案如何:

id -Gnz | tr "\0" "\n"

【讨论】:

    猜你喜欢
    • 2016-04-21
    • 2023-03-24
    • 1970-01-01
    • 2014-03-02
    • 2020-10-08
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多