每行输出一个组,包括组名和组ID

时间:2018-05-17 01:55:50

标签: regex bash awk sed

以下是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)

5 个答案:

答案 0 :(得分:5)

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 !!!

答案 1 :(得分:5)

awk -v RS=, -F'[()=]' '{print "\047"$(NF-1)"\047,"$(NF-2)}'

e.g。给出这个输入数据:

$ 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

答案 2 :(得分:3)

关注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

OR

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

OR

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=, 

答案 3 :(得分:2)

$ 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 输出额外的打破了最后一行:

'',

答案 4 :(得分:2)

使用sed和awk:

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