0

我得到了这个文件

root:
    admin = true
    SYSTEM = "compat"
    registry = files
    account_locked = false
    su = true
    sugroups = system,security,sec_grp

daemon:
    admin = true
    expires = 0101000070
    account_locked = true

bin:
    admin = true
    expires = 0101000070
    account_locked = true

我想使用 shell 脚本仅打印特定用户及其属性。我尝试使用catgrepawk我还找不到解决方案。

任何想法?

我已经用我的系统(Solaris 9)测试了所有答案。它根本不起作用。我不确定我做错了什么?

4

7 回答 7

2

这是一个快速的sed解决方案:

sed -ne '/^daemon:/,/^$/p' filename

其中包括末尾的空白行,但简短且令人难忘。

另一种策略是在每一行重复节级数据,以使结果对面向行的工具更友好,例如

awk '/^[a-z]/ {user=$1} (NF>1) {$1=user$1; print}' filename

生成此输出:

root:admin = true
root:SYSTEM = "compat"
root:registry = files
root:account_locked = false
root:su = true
root:sugroups = system,security,sec_grp
daemon:admin = true
daemon:expires = 0101000070
daemon:account_locked = true
bin:admin = true
bin:expires = 0101000070
bin:account_locked = true

所以你可以在最后贴上一个| grep whoever来查看该用户的属性。

于 2013-11-04T18:21:51.623 回答
1

一个gnu awk版本:

awk '/^daemon/' RS="\n\n" files
daemon:
    admin = true
    expires = 0101000070
    account_locked = true
于 2013-11-04T19:46:06.360 回答
1

您可以使用awk. 例子:

user=daemon
awk '{if(NF==1 && $1 == "'"$user"':") {flag=1;} else if(NF>1 && flag==1) {print} else {flag=0}}' output.txt

输出:

admin = true
expires = 0101000070
account_locked = true

在这种形式下,awk脚本更具可读性:

{
    if(NF==1 && $1 == "'"$user"':") {
        # set a flag when the desired user name appears
        flag = 1;
    } else if (NF > 1 && flag==1) {
        # print regular lines if flag is 1
        print;
    } else {
        # if another user name appears reset the flag
        flag = 0;
    }
}
于 2013-11-04T18:12:53.950 回答
1
awk '$1 == "daemon:"' RS= input-file

当 RS 是空字符串时,awk 将段落视为记录,并且您的格式被方便地布置,以便第一个字段 ($1) 是用户名。

于 2013-11-04T21:45:42.207 回答
1

用 awk 真的很简单:

$ awk '/^daemon:$/,/^$/' file
daemon:
    admin = true
    expires = 0101000070
    account_locked = true

或者,如果您希望用户来自变量,您可以执行以下操作:

awk -v u="$daemon" '$0 == u,/^$/' file
于 2013-11-04T18:57:55.813 回答
1

使用

$ param1=root param2=registry perl -lane '
     if (/^(\w+)/) {
         $key = $1
     }
     else{
         $h->{$key}->{$F[0]} = $F[2]
     }
     END{print $h->{$ENV{"param1"}}->{$ENV{"param2"}}}
' file 

输出:

files
于 2013-11-04T18:25:23.460 回答
1

假设您知道行号是什么:-

sed -n '9,12p' file > output_file

否则,第一个答案是完美的。无论如何,第一个答案可能更好,因为它是动态的;您将获得整个守护程序节,无论它占用多少行。如果您使用行地址并且它们发生变化,则脚本会中断。

于 2013-11-04T19:56:45.257 回答