Isso faz isso. Irritantemente, |
, (
e )
precisam escapar.
sed -i 's/^\(enable\|disable\) telnet/disable telnet/g' /usr/test.log
Eu tenho um arquivo ( /usr/test.log
) com um monte de linhas, da forma
[enable/disable] [name] [stuff]
Por exemplo:
enable telnet max_pkt 0 max_payload 0 min_payload 1 disable_function 0 inherit_max_packets 0
enable telnets max_pkt 0 max_payload 0 min_payload 0 disable_function 0 inherit_max_packets 0
disable teredo max_pkt 0 max_payload 0 min_payload 40 disable_function 0 inherit_max_packets 0
Dado um nome e um status ("enable" ou "disable"), o que é um comando sed
para substituir a linha que contém o nome dado pelo status fornecido? Por exemplo, dado "telnet" e "disable", mudaria a primeira linha acima para
disable telnet max_pkt 0 max_payload 0 min_payload 1 disable_function 0 inherit_max_packets 0
Se houver maneiras mais simples de fazer programaticamente essas operações a partir da linha de comando sem usar sed
, tudo bem também.
Se você sabe o que quer substituir, é apenas
sed -i 's/^enable telnet /disable telnet /g' filename
Desde que a carga útil esteja entre [ativar / desativar] [nome], isso deve ser aceitável. O caractere "^" deve corresponder ao início da linha.
Se você quiser trocar o valor, independentemente do estado atual, então você pode usar ramificação no sed
sed 's/^enable telnet /disable telnet /g
b end #go to end if first rule has matched
s/^disable telnet /enable telnet /g
:end' filename
Com o AWK:
tmp=$(mktemp); awk '$2=="telnet" {$1="disable"} {print}' test.log > $tmp && mv $tmp test.log
O texto acima irá escrever disable
na linha telnet
.
Escrevendo:
#!/bin/sh
file=/path/to/test.log
usage() {
cat <<-USAGE
Enable/disable services in $file
usage: ${0##*/} SERVICE [enable|disable]
positional arguments:
SERVICE service name
USAGE
exitstatus=${1:-1}
exit $exitstatus
}
error() {
printf '%s: error: %s\n' "${0##*/}" "$1" 1>&2
[ -z "$2" ] || exit $2
}
success() {
printf '%s: Service '%s' %sd\n' "${0##*/}" "$service" "$status"
}
[ -f "$file" ] || error 'File not found.' 2
tmp=$(mktemp)
[ $# -eq 0 ] && usage
if [ $# -ne 2 ] || ( [ "$2" != "enable" ] && [ "$2" != "disable" ] ); then
error 'Argument error.'
usage 3
fi
service=$1
status=$2
awk -v status="$status" -v service="$service" -v ok=99 \
'$2==service {$1=status; ok=0} {print} END{exit ok}' "$file" > $tmp
awkexit=$?
case $awkexit in
0 ) mv $tmp "$file" && success;;
99) error 'Service not found.' 4;;
* ) error 'Unkown error. Status change failed.' 5;;
esac
Altere file
para ser o caminho real para o arquivo em questão. Salve o script como, por exemplo, myservice
, torne-o executável, coloque-o no seu PATH
e então ele pode ser executado como:
$ myservice telnet disable
myservice: Service 'telnet' disabled.
O script informará se a mudança de status foi bem-sucedida ou se o serviço não existia no arquivo fornecido. Eu "abusei" do código de saída do AWK para verificar o status da alteração.
Tags sed