Como faço para listar todas as linhas depois que dois padrões subsequentes são correspondidos quando não são

2

Eu tenho arquivos que são usados para instalar arquivos com um proprietário específico: grupo e permissões. Eu vou ignorar permissões para clareza e os detalhes de instalação de arquivos. Uma vez proprietário e amp; group são definidos para um par específico e, em seguida, desejo imprimir uma linha separadora seguida por todas as linhas subsequentes até que o proprietário ou grupo seja alterado. Se eu pudesse imprimir os números de linha com as linhas, isso seria ótimo também. O par que estou procurando é proprietário, grupo como ownerX, groupY, respectivamente.

Exemplo (eu não preciso de números de linha, então vou deixá-los fora)

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>  

Então, a saída desejada seria:

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

Isso me ajudaria a aplicar as seguintes correções:
Alterar o 1º modo de 0750 (grupo é só de leitura) para 0770.
Mude o segundo modo de 0540 (o grupo não pode executar) para 0550.

    
por Tony V 29.12.2015 / 00:13

2 respostas

2

Você pode usar awk com dois sinalizadores, por exemplo:

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

, portanto, só imprimirá quando ambos forem 1 / true. Se você quisesse imprimir apenas as linhas correspondentes a mode junto com seus números de linha, você poderia adicionar outra condição:

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
    
por 30.12.2015 / 21:09
0

don_crissti, obrigado! Isso me deixou muito perto. Funcionou se o arquivo começar com:

group = groupY
owner = ownerX

Mas perdeu se o dono veio primeiro:     owner = ownerX     group = groupY

Usando sua solução e encontrando um tutorial on-line do awk, eu o modifiquei para capturar os dois casos. Embora eu originalmente não tenha solicitado isso, estou interessado apenas nas configurações do modo. Então, ao invés de imprimir todas as linhas dentro de um intervalo, estou imprimindo apenas as linhas que contêm o modo. Problema resolvido:

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 
    
por 30.12.2015 / 19:49