Provavelmente, a melhor coisa a fazer aqui é apenas grep para a linha comentada primeiro:
grep -q '^# deb.*multiverse' /etc/apt/sources.list &&
sed -i '/^# deb.*multiverse/ s/^# //' /etc/apt/sources.list &&
apt-get update
Eu quero habilitar o repositório multiverse no Ubuntu por uma linha de comando.
sed -i "/^# deb.*multiverse/ s/^# //" /etc/apt/sources.list && apt-get update
Esse comando executará apt-get update todas as vezes, mas será necessário somente quando sed comentar a linha.
Existe uma maneira fácil de detectar se sed substitui strings e executa um comando dependendo desse resultado?
Eu sei que esta pergunta já tem uma resposta, mas fiquei curioso para ver se poderia chegar a uma resposta somente para o sed (sem usar o grep como na resposta aceita). Como se vê, parece possível:
sed -ni '/^# deb.*multiverse/{;h;s/^# //;};p;${;g;/^#/!q1;}' /etc/apt/sources.list
&& apt-get update
(Claro, tudo deve estar na mesma linha, mas eu queria que tudo ficasse visível sem ter que rolar horizontalmente).
Explicação:
/^# deb.*multiverse/ ) h ) s/^# // ) $ )
g ) /^#/ ) 1 para sinalizar que nenhuma substituição foi feita ( !q1 ) (senão sai normalmente com o código 0 ) Agora eu sei que esta resposta não é tão clara quanto simplesmente usar o grep, mas eu estava interessado no desafio e descobri isso, então eu pensei em compartilhar.
{ sed -i '/^# \(deb.*multiv.*\)/h;s///p
$x;s//apt-get update/w /dev/fd/2' file
} 2>&1 >/dev/null | sh -v
Esse comando emitirá apenas a linha apt-get update alimentada para sh sobre um pipe se ele fizer pelo menos uma substituição ao ler file .
sed não tem variáveis. Há o comando t que salta para um rótulo após um s/// bem-sucedido e o comando q recebe um código de saída. Mas como você está reescrevendo o arquivo, não é possível sair após a substituição, você precisa ler o arquivo inteiro primeiro.
Eu mudaria para outro idioma. perl trabalha aqui: novas linhas para legibilidade
perl -i -pe '
BEGIN {$x=1}
if (/^# deb.*multiverse/) {s/^# //; $x=0}
END {exit $x}
' /etc/apt/sources.list &&
apt-get update
Outra maneira de fazer isso é com ed , aproveitando-se de um recurso interno: se nenhuma substituição for feita nas linhas endereçadas, isso é considerado um erro; se a entrada padrão for um arquivo regular, ed deverá terminar com um status de saída diferente de zero .
Você poderia usar herestring :
ed -s /etc/apt/sources.list <<< $',s/^# \(deb.*multiverse\)/\1/\nw\n!apt-get update\nq'
ou heredoc :
ed -s /etc/apt/sources.list <<IN
,s/^# \(deb.*multiverse\)//
w
!apt-get update
q
IN
para passar os seguintes comandos para ed :
,s/^# \(deb.*multiverse\)// replace pattern with something
w write changes to file
!apt-get update run this command in shell
q quit editor
No entanto, se nenhuma correspondência for encontrada, significa que não há s ubstitution, então ed explode (a única saída é um ponto de interrogação ? significando error 1 ) e como resultado, os subcomandos nas linhas subsequentes não são executados. Para testá-lo, você pode substituir apt-get update por outro comando como cat /etc/apt/sources.list ou echo DONE .
1:
Se o ponto de interrogação lhe incomoda, basta redirecionar stderr para /dev/null , por exemplo:
ed -s /etc/apt/sources.list 2>/dev/null <<....
Tags sed