Comando avançado do sed

0

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.

    
por Randomblue 22.02.2013 / 12:41

3 respostas

1

Isso faz isso. Irritantemente, | , ( e ) precisam escapar.

sed -i 's/^\(enable\|disable\) telnet/disable telnet/g' /usr/test.log
    
por 22.02.2013 / 13:04
1

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
    
por 22.02.2013 / 12:50
1

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.

    
por 22.02.2013 / 14:05

Tags