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