高级 sed 命令

高级 sed 命令

我有一个文件(/usr/test.log),里面有很多行,格式如下

[enable/disable] [name] [stuff]

例如:

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

给定一个名称和状态(“启用”或“禁用”),sed用给定状态替换包含给定名称的行的命令是什么?例如,给定“telnet”和“禁用”,它会将上面的第一行更改为

disable telnet max_pkt 0 max_payload 0 min_payload 1 disable_function 0 inherit_max_packets 0

如果有更简单的方法可以从命令行以编程方式执行这些操作而无需使用sed,那也很好。

答案1

这样就完成了。令人讨厌的是,|()需要转义。

sed -i 's/^\(enable\|disable\) telnet/disable telnet/g' /usr/test.log

答案2

如果你知道你想替换什么,那么

sed -i 's/^enable telnet /disable telnet /g' filename 

只要有效载荷现在位于 [enable/disable] [name] 之间,这应该没问题。“^”字符用于匹配行的开头。

如果您想不管当前状态如何都交换值,那么您可以在 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

答案3

使用 AWK:

tmp=$(mktemp); awk '$2=="telnet" {$1="disable"} {print}' test.log > $tmp && mv $tmp test.log

上面会写disable在行telnet里。

编写脚本:

#!/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

更改file为相关文件的真实路径。将脚本另存为例如myservice,使其可执行,将其放入您的PATH,然后可以像这样执行:

$ myservice telnet disable
myservice: Service `telnet` disabled.

脚本将告诉您状态更改是否成功或服务是否在给定文件中不存在。我“滥用” AWK 的退出代码来检查更改的状态。

相关内容