Encontre uma string (como grep -q) dentro de apenas uma seção de um arquivo

4

Eu quero escrever algum Bash que possa verificar se existe uma string em um arquivo de configuração. Não consigo alterar o formato do arquivo, ele pertence a um aplicativo diferente.

O arquivo é subdividido em grupos nomeados por strings entre colchetes.

Isso deve ser um sucesso:

[group1]
MyParameter
junk1
junk2

[group2]
junk3
junk4

Isso deve ser um erro:

[group1]
junk1
junk2

[group2]
MyParameter
junk3
junk4

Eu posso fazer um grep -q para verificar se MyParameter existe no arquivo, mas se ele estiver em outro grupo e não em group1 , então ainda estou preso.

Se MyParameter existisse nos dois grupos, eu não me importaria o suficiente para sinalizar um erro, contanto que ele existisse em group1 .

Eu não posso depender de números de linha (cabeça, cauda, etc). Além disso, eu ficaria mais feliz se fosse genérico o suficiente para não depender do nome de group2 (o script saberia apenas se ele encontrasse outra linha começando e terminando com colchetes, que terminaria o grupo anterior) .

    
por twblamer 04.11.2011 / 22:09

4 respostas

7

Sempre que se deparar com um problema de processamento de texto, algumas pessoas dizem "vamos usar o awk". Mais frequentemente do que não, eles têm uma solução.

awk '
    /^\[.*\]$/ {group = $0}
    group == "[group1]" && $1 == "MyParameter" {found=1; exit}
    END {exit !found}
'
    
por 04.11.2011 / 23:17
3

Com o GNU sed você pode fazer

sed -n '/\[group1\]/,/\[group2\]/{/MyParameter/p}' input-file

que gravará MyParameter apenas quando estiver na seção group1 . Se a seção após group1 não for sempre group2 , você poderá substituir group2 por .* .

    
por 04.11.2011 / 23:06
2

Aqui está um script Perl que deve fazer o trabalho:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 group pattern [file...]\n" if scalar @ARGV < 2;

my $group = shift;
my $pattern = shift;

my $curr_group = undef;
my $matched = 0;
while (<>) {
    if (/^\[(.*)\]/) {
        $curr_group = $1;
    }
    else {
        if (defined $curr_group and 
            $curr_group eq $group and 
            /$pattern/) 
        {   
            print "Match\n";
            $matched = 1;
        }
    }
}

if (not $matched) {
    print "No match\n";
}
    
por 04.11.2011 / 22:15
0
if [ 'egrep 'MyParameter|^\[.*\]$' file.conf | head -2 | tail -1' == "MyParameter" ]
then 
  echo Success
else 
  echo Failure
fi
    
por 04.11.2011 / 22:39