Na verdade, não é uma linha única, mas você poderia fazer isso com uma invocação de sed
:
sed -e '
/pat/{s//repl/g;h;}
$!b
G
s/\n..*//;t
s/$/repl/
' yourfile
N.B .: Eu deliberadamente usei pat
e repl
para padrão e substituição, respectivamente, e não as variáveis de shell como você fez. Basicamente por 2 razões principais, eles iriam atrapalhar o fluxo do código sed + para correção, precisamos citar ambos, e diferentemente, para fazê-los funcionar. Esse trabalho eu deixo para você.
Fluxo: Digamos, o arquivo nunca teve um / pat / então todas as linhas são tomadas para stdout pelo comando $! b e a última linha quando anexada por G apenas vê uma espera vazia
então o t
não é tirado e temos uma operação de acréscimo.
Quando vemos uma linha / pat /, então é s /// - ed e a área de espera está marcada. se não for a última linha, simplesmente saímos para a stdout. Para eof, fazemos uma verificação de espera e, como não está vazia (assumindo que repl
é NONEMPTY
, o caminho de teste seria obtido após remover a retenção do espaço de padrão.
Perl
oferece a clareza para corresponder à intenção palavra por palavra no código:
perl -lne '$a += s/pat/repl/g,print}{print q[repl] unless $a'
Para ser lido como: A variável $a
serve como contador para o número de substituições. No final, adicionaríamos ao arquivo quando não houvesse subscrições feitas anteriormente.
E quanto ao fornecimento de informações de padrão / substituição por meio de variáveis, podemos fazer isso:
WHAT_I_WANT='my line of text = something'
WHAT_TO_REPLACE='my line of text = .*'
FILE_TO_EDIT=conf_file.conf
perl -li -sn -e '
$a += s/$pat/$repl/g,print}{print $repl unless $a
' -- -pat="$WHAT_I_WANT" -repl="$WHAT_TO_REPLACE" -- "$FILE_TO_EDIT"