我正在尝试为CentOS服务器自动化一些东西。对于这种自动化,我需要添加,替换或修改文件行。这可以通过全局替换或替换唯一行来正常工作。
sed -i "s/user \\= apache/user \\= nginx/" file.conf
这会将user = apache
替换为user = nginx
,但效果正常。
但有时我需要在其他正则表达式的结果中替换这些行。例如,文件/etc/php-fpm.d/www.conf
包含serval时间的相同配置行。
使用正则表达式,我可以轻松过滤掉我想要替换的部分,但我不知道该怎么做。
这是文件的一部分:
...
[base]
name=CentOS-$releasever - Base
baseurl=http://centos.mirrors.ovh.net/ftp.centos.org/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
exclude=postfix
[updates]
name=CentOS-$releasever - Updates
baseurl=http://centos.mirrors.ovh.net/ftp.centos.org/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
exclude=postfix
[extras]
name=CentOS-$releasever - Extras
...
这个正则表达式:
sed -n "/\[base\]/,/\[updates\]/p" /etc/yum.repos.d/CentOS-Base.repo
我可以从[base]到[updates]获取行。然后我可以修改例如exclude
行。但是如何将这些行重新放回主文件中?
这是我到目前为止所做的:
# $BASE contains the lines [base] until [updates]
BASE=`sed -n "/\[base\]/,/\[updates\]/p" /etc/yum.repos.d/CentOS-Base.repo`
# Get te line that holds 'exclude' to the $EXCLUDE parameter
EXCLUDE=`echo "$BASE" | grep "exclude"`
# Modify EXCLUDE
EXCLUDE="$EXCLUDE, dovecot"
# Replace old exclude line in $BASE variable with new one
BASE=`sed "s/^exclude.*/$EXCLUDE/g" $BASE`
# Put $BASE back into /etc/yum.repos.d/CentOS-Base.repo
# ???
在这个脚本中,我试图通过多个命令实现这一点,这很好。如果只有一个替换表达式也会很好。但那当然不是必须的。
答案 0 :(得分:0)
sed -i "/\[base\]/,/\[updates\]/s/^exclude.*/&, dovecot/"
sed
命令由可选地址,命令和命令的任何参数组成。地址(如果存在)是指示行号的单个表达式或标识要应用命令的行的单行模式,或者是指示开始和结束行号或模式的一对逗号分隔表达式。命令的应用范围。
您之前的sed
脚本("/\[base\]/,/\[updates\]/p"
)使用p
(打印)命令,地址范围为/\[base\]/
到/\[updates\]/
。
您可以将s
(替代)命令应用于同一范围,以exclude.*
替换&, dovecot
(排除后跟任何内容 - 但吞噬其余部分) (替换字符串中的&
表示匹配的所有内容。)
如果您需要在该地址范围内执行更复杂的操作,可以使用{
sed命令 - 这将打开一个以}
命令终止的命令块。这可以让你做if / else块之类的事情,所以你可以这样做:
sed -i -e "/\[base\]/,/\[updates\]/{" \
-e "/\[base\]/h" \
-e "s/^exclude=.*/&, dovecot/" \
-e "/^exclude=/h" \
-e "/\[updates\]/{" \
-e "x" \
-e "/^exclude=/b e" \
-e "i \
exclude=dovecot" \
-e ": e" \
-e "x" \
-e "}" \
-e "}" /etc/yum.repos.d/...
这个大毛茸茸的sed脚本执行以下操作:
[base]
和[updates]
行之间运行。[base]
行或任何以exclude=
开头的行都会被放入" hold"缓冲区(通过h
命令)exclude=
开头的行都会附加, dovecot
[updates]
时:
hold
缓冲区(通过x
命令将当前行交换为hold
缓冲区)exclude=
b
}分支到标签e
exclude=dovecot
e
后(通过命令:
)...... hold
缓冲区(再次通过x
)换句话说:任何exclude=
行都会附加, dovecot
个;如果未看到exclude=
行,则会在结尾添加新的exclude=dovecot
行。
请注意,从/\[base\]/
转到/^$/
可能更有用,如果您可以保证每个块末尾的空行(通常是这种情况),在这种情况下,您将更新第一个-e
表达式以及将-e "/\[updates\]/{"
更改为-e '/^$/'{
(还请注意引号的更改,以便$
不会被shell解析)。