Como testar a presença de uma string antes de outra string em linhas separadas em um arquivo

0

Eu tenho um arquivo de configuração assim:

a: 123
b: abc
device: 1000
c: xyz

[old]
a: 120
b: xyz
device: 200
c: abc

A seção "[old]" e tudo abaixo dela nem sempre estão presentes.

Como posso determinar se o texto "dispositivo: 1000" existe no arquivo ANTES de uma seção opcional "[antiga]"?

Eu tenho andado com a seguinte sintaxe de comando (quebrada) e não consigo fazer o que eu preciso ...

sed -e '0,/^\[/;  /device: /p' configfile ; echo $?

... onde 0,/^\[/ deveria limitar a pesquisa entre o início do arquivo e a primeira ocorrência de "[" na primeira coluna. Estou tentando obter o código de retorno para indicar se a string foi encontrada ou não.

    
por Wossname 26.10.2018 / 13:03

3 respostas

1

Se awk for uma opção:

awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file

Explicação:

  • BEGIN{o=d=1} : inicializa as variáveis
  • /\[old\]/{o=0} if [old] : é encontrado definido o=0
  • /device: 1000/&&o==1{d=0;exit} : se device: 1000 for encontrado e [old] ainda não for encontrado, defina d=0 e vá para o bloco END{} sem examinar o arquivo ainda mais.
  • END{exit d} : sair com o valor fornecido de d

Execute assim:

awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file && echo "contains" || echo "contains not"
    
por 26.10.2018 / 13:16
1

Você pode procurar por device: 1000 depois de ter removido tudo depois de [old] :

if sed '/^\[old\]/q' < file | grep -q 'device: 1000'; then
  echo OK
fi

Com o GNU sed (que você parece estar usando dado o 0,/.../ específico do GNU em sua abordagem).

if sed -n '/device: 1000/q; /^\[old\]/Q1' < file; then
  echo OK
fi

( q , forma padrão de Q0 sai com um status de saída 0 (com êxito), enquanto Q1 sai com status de saída 1 (diferente de zero, portanto, não é bem-sucedido)).

Com o padrão sed , você não pode alterar o status de saída de sed , mas pode confiar se ele gera algo:

if [ -n "$(sed -n '/^\[old\]/q;/device: 1000/!d;=;q' < file)" ]; then
  echo OK
fi

(onde = produz o número da linha onde a primeira ocorrência de device: 1000 é vista).

Ou você pode usar awk , que pode definir o status de saída como portável:

if awk '$0 == "[old]" {exit 1}; /device: 1000/ {exit 0}' < file; then
  echo OK
fi
    
por 26.10.2018 / 13:22
0

Eu normalmente crio um blob com sed, capturando várias linhas para uma variável. Isso permite uma inspeção mais tarde, se a condição exigida for atendida.

blob=“$(sed -n “/^abc.*$/,/^$/p” file)”

Agora, temos a parte superior do arquivo atribuída a ”${blob}” .

Agora, apenas inspecionamos condicionalmente ${blob} de [old] :

sh if [ $(grep -c “^\[old/]$” file) -gt 0 ]; then echo “${blob}” | grep “^device” | grep -c 1000 fi

Tenho certeza de que isso pode ser refatorado, mas isso fornecerá os resultados desejados.

    
por 26.10.2018 / 13:16