Shell脚本在匹配后显示多行

时间:2013-11-04 18:00:56

标签: shell unix awk grep cat

我收到了这个文件

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)。它根本不起作用。我不确定我做错了什么?

7 个答案:

答案 0 :(得分: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以查看该用户的属性。

答案 1 :(得分: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;
    }
}

答案 2 :(得分: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

答案 3 :(得分:1)

使用awk非常简单:

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

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

awk -v u="$daemon" '$0 == u,/^$/' file

答案 4 :(得分:1)

gnu awk版本:

awk '/^daemon/' RS="\n\n" files
daemon:
    admin = true
    expires = 0101000070
    account_locked = true

答案 5 :(得分:1)

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

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

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

答案 6 :(得分:1)

awk '$1 == "daemon:"' RS= input-file

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