【问题标题】:Output groups one per line, with group name and group ID每行输出一个组,带有组名和组 ID
【发布时间】:2018-10-27 04:18:39
【问题描述】:

这里是关于我所属组的信息,来自id 命令。 我已经做到了,所以输出会更容易阅读。我将这个输出“完全”包括在内,因为它是从命令行返回的。 (感谢@EdMorton。)

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

这是我想要的输出,以逗号分隔,每行有一个组名及其 GID:

$ some-great-command
'Users',545
'CONSOLE LOGON',66049
'Authenticated Users',11
'CurrentSession',4095
'LOCAL',66048

我想出了一个可怕的方法来做到这一点:

$ id | sed 's/\(.*groups=\)\(.*$\)/\2/' | awk -F "," '{ for(i = 1; i <= NF; i++) print $i;}' | sed 's/\(^[[:digit:]]\+\)[(]\([A-Za-z +_]\+\)[)]$/'"'"'\2'"'"',\1/'

(我会用更好的屏幕格式再次放在这里,使用\

$ id | sed 's/\(.*groups=\)\(.*$\)/\2/' | \
awk -F "," '{ for(i = 1; i <= NF; i++) print $i;}' | \
sed 's/\(^[[:digit:]]\+\)[(]\([A-Za-z +_]\+\)[)]$/'"'"'\2'"'"',\1/'

但我不禁认为必须有更好的(或者至少更短更优雅)的方式来完成这个过程。任何人都可以分享这样的解决方案吗?

注意:我这样做的一个原因是,有时,getent group GID 在我工作的地方有点挑剔。我看过其他一些帖子,例如this one,但它没有我想要的答案。

id 输出的更好阅读版本与控制台提供的不同!在(Users)(注意右括号后的空格)和(LOCAL),(逗号后没有空格)之后有换行符。

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

真实id输出:

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

【问题讨论】:

  • 非常好的和详细的帖子!!!很高兴回答!如果所有帖子都可以这样......
  • @EdMorton。正如您所怀疑的那样,我将删除“更易于阅读”的部分,这是一个额外的换行符。感谢您的提示!
  • 感谢您的评论,@Allan!

标签: regex bash awk sed


【解决方案1】:

关注awk 可能对您有所帮助。

awk -v s1="'" -F"[)(=,]"  '/uid/{print s1 $(NF-1) s1 OFS $(NF-2);next} /groups/{print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next} /CurrentSession/{print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2)}' OFS=,  Input_file

id | awk -v s1="'" -F"[)(=,]"  '/uid/{print s1 $(NF-1) s1 OFS $(NF-2);next} /groups/{print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next} /CurrentSession/{print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2)}' OFS=, 

现在也添加非单线形式的解决方案。

awk -v s1="'" -F"[)(=,]"  '
/uid/                    {  print s1 $(NF-1) s1 OFS $(NF-2);                          next}
/groups/                 {  print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next}
/CurrentSession/         {  print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2);         }
' OFS=,   Input_file

id | awk -v s1="'" -F"[)(=,]"  '
/uid/                    {  print s1 $(NF-1) s1 OFS $(NF-2);                          next}
/groups/                 {  print s1 $6 s1 OFS s1 $5 s1 ORS s1 $(NF-2) s1 OFS $(NF-3);next}
/CurrentSession/         {  print s1 $2 s1 OFS $1 ORS s1 $(NF-1) s1  OFS $(NF-2);         }
' OFS=, 

【讨论】:

  • @Allan 你说a bit long 吗?
  • 谢谢!我不确定我应该使用什么作为Input File。对于第一个版本(awk 之前的id。)这只是$ id &gt; Input_file 还是某个系统文件?
  • @bballdave025,我也添加了id | awk command...,看看对你有没有帮助?
  • 他们确实帮助了我。它特别帮助我了解发生了什么。
【解决方案2】:

还有perl

$ id | perl -pe "s/.*=/,/;s/,(\d+)\(([^)]+)\)/'\2',\1\n/g"                                                                 
'arobert',1000
'adm',4
'cdrom',24
'sudo',27
'dip',30
'plugdev',46
'lpadmin',113
'sambashare',128

说明:

将执行两个查找和替换命令:

  • s/.*groups=/,/ 用于删除组定义之前的所有内容
  • s/,(\d+)\(([^)]+)\)/'\2',\1\n/g 将采取以下措施详细说明@demo

很难写出比这更短的东西。 此外,如果您已经精通sedregex,那么perl 可能是添加到您的技能列表中的一个不错的加分项。

正如Ed Morton 所述,当前的perl 命令在输出末尾生成一个额外的EOL。如果要删除它,可以使用以下增强的perl 命令:

$ id | perl -pe "s/.*=/,/;s/,(\d+)\(([^)]+)\)/'\2',\1\n/g;s/\n\n/\n/"

谢谢Ed!!!

【讨论】:

  • @EdMorton:谢谢!我已经相应地调整了perl 命令。
  • 我应该提到我不在乎答案是否是awksed。为了优雅(或者可能只是简洁)和一个很好的解释,这个被接受了。我肯定会刷掉我的perl 技能,让它成为我“技能列表”的一部分。谢谢!
  • P.S.我验证了这一点。我想我必须在我的.bashrc:alias some-great-command="id | perl -pe "s/.*=/,/;s/,(\d+)\(([^)]+)\)/'\2',\1\n/g;s/\n\n/\n/"" 中添加 类似 的行。我只需要弄清楚escapes! :)
【解决方案3】:
$ id |
  awk 'BEGIN{ RS=OFS=",";q="\047" }
  {
      n=split($0,a,"=")
      split(a[n],a,"[()]")
      print q a[2] q,a[1]
  }'
'Users',545
'CONSOLE LOGON',66049
'Authenticated Users',11
'CurrentSession',4095
'LOCAL',66048

与 gawk 和 mawk 配合得很好,但是 bwk 输出了一个额外的 打破了最后一行:

'',

【讨论】:

  • 哇这个awk的答案太棒了~~~+1!!!想知道它是否比我的 perl 解决方案短哈哈
  • 很遗憾没有。
【解决方案4】:
awk -v RS=, -F'[()=]' '{print "\047"$(NF-1)"\047,"$(NF-2)}'

例如给定这个输入数据:

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

并使用cat file 代替id

$ cat file | awk -v RS=, -F'[()=]' '{print "\047"$(NF-1)"\047,"$(NF-2)}'
'Users',545
'CONSOLE LOGON',66049
'Authenticated Users',11
'CurrentSession',4095
'LOCAL',66048

【讨论】:

  • 我真的很喜欢这个。我 +1-ed 它,因为它像我一样使用awk。我将我的id 输出通过管道传送到命令,它就像一个魅力。谢谢! P.S.,这将以最少字节赢得CodeGolf 挑战...让我检查一下...
  • 这和@Allan's 之间是一场硬仗。
  • $ echo 'awk -v RS=, -F'"'"'[()=]'"'"' '"'"'{print "\047"$(NF-1)"\047,"$(NF-2)}'"'"'' | wc -m 给出60。这将是 CodeGolf 的赢家(至少如果我们使用 @Allan 的命令来消除额外的 EOL)。
【解决方案5】:

使用 sed 和 awk :

$ id | sed 's/,/\n/g' | awk -F '[()=]' '{print $(NF-1)","$(NF-2)}'

【讨论】:

  • 我必须 +1 这个,因为你使用了与我相同的工具,但对它进行了 elegan 化。
  • 它没有在组名周围加上单引号,这是我应用命令时需要的。我确信这很容易解决。我试图弄清楚如何将escape sequence 放入awk 命令中,但无法使其工作。
  • @bballdave025,是的,它只显示你有多接近。 !
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多