pt sed repetindo a última linha no fluxo

3

Eu tenho código em um script semelhante a este ...

smbconffile="/etc/samba/smb.conf"
sed -i 's/.*[\[CMI\]]/\[CMI\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[LOCAL\]]/\[LOCAL\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[NATIONAL\]]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || "Failed"

isso muda os nomes dos compartilhamentos no samba conf (smb.conf) para o CMI $, LOCAL $, NACIONAL $.

o problema que estou tendo é que, após o segundo comando sed, sed encontra "NATIONAL", mas o renomeia como "LOCAL $" em vez de "NATIONAL $". Alguém vê um problema com os comandos? Qualquer ajuda seria muito apreciada.

    
por Matt Pedigo 15.12.2014 / 22:20

1 resposta

4

Você está misturando classes de personagens (uma lista de caracteres dentro de colchetes) com os nomes de compartilhamento smb.conf que estão rodeados por literais colchete. Além disso, o comando echo não é bem formado:., No caso onde sed saídas com um status diferente de zero, o shell tentará chamar o comando Failed

Algumas sugestões:

  1. Remover a classe de caracteres (colchetes externos)
  2. Remova o .* inicial que removerá os comentários principais, etc.
  3. Executar um único comando sed com várias instruções
  4. Corrigir a mensagem do caso de erro


sed -i 's/\[CMI\]/\[CMI\$\]/;
        s/\[LOCAL\]/\[LOCAL\$\]/;
        s/\[NATIONAL\]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || echo "Failed"'

Você pode usar referências anteriores para evitar redigitação o prefixo original na expressão de substituição (por exemplo, '[CMI'), mas que pode tornar as expressões ainda mais difícil de ler.

Outra sugestão é usar Perl que tenha agrupamento legível e backreferences IMO:

perl -pi -e 's/(\[(?:CMI|LOCAL|NATIONAL))\]/$1\$]/g' $smbconffile \
    && echo "Success" || echo "Failed"


Editar: Para esclarecer, o problema com a expressão original com os suportes exteriores é que você está criando uma classe de caracteres que corresponde a qualquer cadeia que contenha (no primeiro caso) [ , C , M , I , ] em qualquer ordem seguido por ] . Por exemplo:

$ echo '[IMC]' | sed 's/[\[CMI\]]/[something_else]/'
[IM[something_else]

$ echo '[FOOM]' | sed 's/[\[CMI\]]/[something_else]/'
[FOO[something_else]

A remoção dos colchetes externos remove a classe de caractere para que a expressão corresponda à substring exata fornecida.

    
por 15.12.2014 / 22:44