descomentando o código específico em um arquivo maior

2

Eu tenho essas linhas de código no meu arquivo /etc/bash.bashrc no Ubuntu 15. Como posso descomentar apenas as linhas da linha de comando, sem sem atrapalhar nenhum outro comentário no arquivo?

# enable bash completion in interactive shells
#if ! shopt -oq posix; then
#  if [ -f /usr/share/bash-completion/bash_completion ]; then
#    . /usr/share/bash-completion/bash_completion
#  elif [ -f /etc/bash_completion ]; then
#    . /etc/bash_completion
#  fi
#fi

O resultado desejado deve ser assim:

# enable bash completion in interactive shells
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

Lembre-se de que existem outras linhas de código neste arquivo que não quero atrapalhar e que isso deve ser feito automaticamente por um script bash.

    
por Asaf Magen 09.09.2015 / 15:08

6 respostas

1

Na verdade, o que é perguntado é uma maneira muito errada de fazer multiprofiles bashrc. Você deve ter vários arquivos .bashrc diferentes, como .bashrc_1, .bashrc_rc2, onde define sua necessidade diferente do arquivo .bashrc básico e os fornece quando necessário.

É isso.

    
por 09.09.2015 / 15:35
1

Não posso dar uma resposta definitiva sem ver o arquivo inteiro. Se houver apenas uma instância de if ! shopt -oq posix; e 'você pode usar isso para delimitar a seção relevante:

perl -i -pe '$i++ if /^#if ! shopt -oq posix;/; s/^#// if $i==1; $i=0 if /^fi/' /etc/bash.bashrc 

Este script define $i a 1 na primeira vez que encontra uma linha que começa com #if ! shopt -oq posix; . Ele volta para 0 se encontrar uma linha começando com fi (não #fi , porque o operador de substituição não terá mais comentários neste ponto). Então, se $i for 1 , ele removerá os comentários do início da linha.

Notas

  • Isso falhará se você tiver mais de uma linha começando com #if ! shopt -oq posix;
  • Ele falhará se você tiver um espaço após o # .

Uma abordagem muito melhor seria editar seu arquivo para que a seção relevante seja claramente delimitada usando outra coisa. Por exemplo, XXXstart e XXXend :

Depois, você pode fazer uma abordagem mais geral:

# enable bash completion in interactive shells
# XXXstart
#if ! shopt -oq posix; then
#  if [ -f /usr/share/bash-completion/bash_completion ]; then
#    . /usr/share/bash-completion/bash_completion
#  elif [ -f /etc/bash_completion ]; then
#    . /etc/bash_completion
#  fi
#fi
#XXXend

Agora, use este script no arquivo:

 perl -i -pe '$i=0 if /XXXend/; s/^\s*#*// if $i==1; $i=1 if /XXXstart/; ' /etc/bash.bashrc

Finalmente, não faça isso. Não mexa com /etc/bash.bashrc . Basta adicionar essas linhas ao seu ~/.bashrc arquivo e evitar alterar /etc/bash.bashrc . Primeiro porque é mais limpo e seguro e segundo porque qualquer alteração feita no arquivo em /etc será sobregravada pela próxima atualização.

    
por 09.09.2015 / 15:40
0
  1. por que não ter um arquivo temporário que você acabou de concatenar para /etc/bash.bashrc ?

    cat /tmp/posix-opt.txt >> /etc/bash.bashrc
    

(isto irá adicionar /tmp/posix-opt.txt (que contém a linha não comentada) ao /etc/bash.bashrc)

  1. Se não for possível

    n=$(grep -n 'shopt -oq posix' /etc/bash.bashrc)
    sed -i -e "$n,$(($n + 7))s/^#//" /etc/bash.bashrc
    

isto é o mesmo que no vi, você só precisa do grep para obter o número da linha.

observe, no entanto, que se houver duas linhas contendo "shopt -oq posix", o script será quebrado.

    
por 09.09.2015 / 15:12
0

Se você souber em qual linha do arquivo seu bloco começa (por exemplo, linha 30), pode fazê-lo com

sed '31,+6s/^.//' </etc/bash.bashrc >/etc/bash.bashrc-uncommented

Em seguida, verifique seu novo arquivo bash.bashrc-uncommented para ter certeza de que está certo antes de copiar

mv /etc/bash.bashrc-uncommented /etc/bash.bashrc

O que a instrução sed está fazendo é procurar a linha 31 (a linha após o início do bloco) e aplicar uma expressão regular às 6 linhas solicitadas.

Para cada linha, a expressão regular procura o início da linha ^ e o caractere seguinte . e a substitui por nada (ou seja, exclui-a).

Os </etc/... e >/etc/... informam sed onde encontrar seu arquivo e onde enviar o resultado do comando.

    
por 09.09.2015 / 18:07
0

Esta solução proposta surgiu e precisa de alguma preparação, mas tudo bem para mim.

Primeiro copiei o arquivo de origem para uma pasta temporária

cp /etc/bash.bashrc /var/ldt/bash.bashrc_modifed

Depois eu edito apenas o que eu precisava em /var/ldt/bash.bashrc_modifed.

Criamos o patch executando:

diff -u /etc/bash.bashrc /var/ldt/bash.bashrc_modifed > /var/ldt/bash.bashrc_patch

Agora, posso aplicar a alteração apenas ao que eu quero exatamente.

patch /etc/bash.bashrc < /var/ldt/bash.bashrc_patch
    
por 09.09.2015 / 18:12
0

Uma solução com o awk:

awk '/shopt -oq posix/ { sub("#","",$0); print; for(n=0; n<=6; n++) { getline ; sub("#","",$0); print} }1' </etc/bash.bashrc >NEWFILE

Em seguida, renomeie NEWFILE para /etc/bash.bashrc ou qualquer outra coisa.

    
por 09.09.2015 / 18:30