如何列出两个后续模式匹配后到不匹配时的所有行

如何列出两个后续模式匹配后到不匹配时的所有行

我有用于安装具有特定所有者:组和权限的文件的文件。为了清楚起见,我将忽略权限和安装文件的详细信息。将所有者和组设置为特定对后,我想打印一个分隔行,然后打印所有后续行,直到所有者或组发生更改。如果我可以打印行号和行号,那就太好了。我正在搜索的对是所有者,组分别为ownerX,groupY。

示例(我不需要行号,所以我将省略它们)

type = d  
owner = root  
group = staff  
    mode = 0750 <-Ignore.  owner & group aren't ownerX & groupY  
    ...  <- Ignore  
group = groupY <- owner=root, not ownerX, so still not ownerX & groupY  
    ...  <- Ignore  
owner = ownerX <-Now, owner=ownerX and group=groupY  
    <- Print -----------------  
    mode = 0750             <- Print  
    target = /app_dir/conf  <- Print   
    target = /app_dir/data  <- Print  
owner = dilbert          <- Stop printing since not ownerX & groupY  
    ...  <- Ignore  
group = Dogbert  
    ...  <- Ignore  
group = groupY  
    ...  <- Ignore  
owner = ownerX  
    <- Print a separator line  
    type = f                                                       <- Print  
    mode = 0540                                                    <- Print  
    source = [path to compiled binary file in source environment]/file1_ver2  <- Print  
    target = [path to a bin directory in the install environment]/file  <- Print  
owner = oracle <- stop printing  
...  
<End of File, EOF>  

因此,所需的输出将是:

---------  
mode = 0750  
target = /app_dir/conf  
target = /app_dir/data  
---------  
type = f  
mode = 0540  
source = [path to compiled binary file in source environment]/file1_ver2  
target = [path to a bin directory in the install environment]/file1  

这将帮助我应用以下修复:
将第一个模式从 0750(组是只读的)更改为 0770。
将第二个模式从 0540(组无法执行)更改为 0550。

答案1

您可以使用awk两个标志,例如:

awk '/group =/{a=0};/group = groupY/{$0="----------";a=1}
/owner =/{b=0};/owner = ownerX/{$0="----------";b=1};a*b' infile

所以只有当两者都为 1/true 时才会打印。如果您只想打印匹配的行mode及其行号,您可以添加另一个条件:

awk '/group =/{a=0};/group = groupY/{$0="------------";a=1};/owner =/{b=0}
/owner = ownerX/{$0="------------";b=1};(($1=="mode") && (a*b==1)){print NR, $0}' infile

答案2

唐克里斯斯蒂,谢谢!这让我非常接近。如果文件开头为:

group = groupY
owner = ownerX

但如果所有者排在第一位,则错过了:owner = OwnerX group = groupY

使用您的解决方案并找到在线 awk 教程,我对其进行了修改以捕获这两种情况。虽然我最初没有要求这样做,但我只对模式设置感兴趣。因此,我不是打印某个范围内的所有行,而是只打印包含模式的行。问题解决了:

awk '/group =/{t=0}
/group = groupY/{t=1}
/owner =/{p=0}
{if ((t==1) && (p==1) && (seperator_printed==0)) {
  print "-------------------------"
  seperator_printed=1
  }
}
{if ((t==1) && (p==1)) {
    if ($0 ~ /mode/) {print NR, $0}
  } else {
    separator_printed=0
  }
}' infile 

相关内容