我有一个文件(/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 的退出代码来检查更改的状态。