Se você quiser substituir uma linha inteira sem regex, também poderá obter o número da linha primeiro:
LNO=$(grep -FN "$pattern" </etc/bashrc | cut -d':' -f1)
e substitua a linha por um padrão comentado e uma nova linha:
[ "$LNO" ] \
&& sed -i "${LNO}s/.*/#$pattern\n$newline/" /etc/bashrc
Este também é mais claro para ler meses depois.
Para fins de teste, eu sempre prefiro sed em um arquivo temporário primeiro (sem a opção -i),
e renomeá-lo mais tarde para não danificar minha configuração.
Mas também descobri que esse método não funciona com padrões que contêm [,],$ and &
; os padrões também precisam de algum mascaramento nessa ordem:
pattern=${pattern//\[/\\[}
pattern=${pattern//\]/\]}
pattern=${pattern//\$/\$}
pattern=${pattern//\&/\&}
pattern=${pattern//\/\\}
que leva à seguinte função:
#!/bin/bash
declare -a commentAndReplaceMask=('[' ']' '$' '&')
function commentAndReplace () {
local p="$1" # pattern
local s="$p" # sed pattern
local r="$2" # replacement
local f="$3" # file
echo args:
echo p: $p
echo r: $r
echo s: $s
s=${s//\/\\}
r=${r//\/\\}
for m in ${commentAndReplaceMask[@]}; do
s=${s//$m/\$m}
r=${r//$m/\$m}
done
echo prepared for sed:
echo p: $p
echo r: $r
echo s: $s
LNO=$(grep -Fn "$p" <$f | cut -d':' -f1)
[ "$LNO" ] \
&& sed "${LNO}s/.*/# $s\n$r/" <$f >${f}.tmp
# mv "${f}.tmp" "$f"
}
commentAndReplace "$@"