场景一
场景描述:找到指定的行,将其注释掉(是直接注释,不是修改值),然后紧接下一行插入新内容
这种场景在修改配置文件时最常见,注释和插入的往往是同一配置项,为了维护配置文件的可读性,通常会将关系紧密的几项配置放在一起,这就是为什么需要紧接下一行插入新内容的原因。
编辑示例:
我们现在要编辑/var/kerberos/krb5kdc/kdc.conf文件,编辑内容为:找到现有的database_name配置项将其注释掉,然后紧邻下一行插入新的配置项(因为两项配置关系密切)。
...
#database_name = /var/kerberos/krb5kdc/principal
database_module = openldap_ldapconf
...
1
2
3
4
编辑命令:
# 找到database_name这一行,将其注释掉;
# 并在下一行插入:database_module = openldap_ldapconf
sed -i 's/\(^\s*\)database_name\(.*\)/\1#database_name\2\n\1database_module = openldap_ldapconf/g' /var/kerberos/krb5kdc/kdc.conf
1
2
3
知识点:
这条sed语句有很多值得学习和复用的地方,总结如下:
^\s*:考虑可能的缩进,增强匹配的适用性
\(, \), \\\|,\1,\2:注意要转义的字符
\1,\2:注意对分组的运用,分组的用处在于能将匹配到的内容作为一个整体“复制”到期望的位置。本例中如果只是想在database_name前加上一个#符号,是用不到分组的,这里用到分组的原因是:替换的字符串要在原字符串的基础上append新内容,这就需要将原字符串中的“缩进部分”和“database_name的后半部分”复制到替换字符串中,因此需要对这两个独立的部分进行“标记”,以便在替换字符串中“引用”
\n:新起一行插入内容
关于grep正则表达式有哪些字符需要转义,可参考:
场景二
场景描述:文件中可能有针对某一项配置的多行记录,有的是生效中的配置,有的是被注释掉的候选配置,需求是找到这些冗余的项,全部移除,然后在原第一行中插入唯一生效的项。
场景二和场景一是有区别的:场景一要注释掉的是一个确定存在且生效中的项,不存在多个注释或未注释的同名项,新插入的项也与注释掉的项不同(仅仅是关系紧密); 场景二的处理的则是可能存在多个注释或未注释的同名项,且新插入的项还是同一项,这样在判断哪些项需要注释,哪些项需要取消取消注释就会非常麻烦,所以方案二的处理策略是:全部移除,以新插入的项为准。这样会带来一个问题,一旦移除这些已有的项,就找不到合适的位置来插入新项了,所以,移除前,需要先把行号记录下来,然后在原第一行处插入,这样,可以保持配置项的上下关联性。
编辑示例:
我们现在要编辑/etc/ssh/sshd_config文件,其内容可能如下,也可能是其他状况,总之会存在多项UsePAM和PasswordAuthentication的行,有的是注释掉的,有的是生效中的:
...
UsePAM no
#UsePAM yes
...
PasswordAuthentication no
#PasswordAuthentication yes
...
1
2
3
4
5
6
7
我们希望编辑后是这个样子:
...
UsePAM yes
...
PasswordAuthentication yes
...
1
2
3
4
5
编辑命令:
items=(UsePAM PasswordAuthentication)
for item in ${items[@]}; do
searchExp="^\s*[#]\?\s*${item}\s*\(yes\|no\)$"
# 所有待删除的行号
lineNums=($(grep -n -e "$searchExp" /etc/ssh/sshd_config | cut -d: -f1))
# 生成sed行表达式
printf -v linesExp "%sd;" "${lineNums[@]}"
# 删除所有行
sed -i -e "$linesExp" /etc/ssh/sshd_config
# 在原第一行处插入新配置(为了保持配置项出现在合适的位置)
sed "${lineNums[0]}i ${item} yes" -i /etc/ssh/sshd_config
done
1
2
3
4
5
6
7
8
9
10
11
12
13
知识点:
grep -n -e '^\s*[#]\?\s*PasswordAuthentication\s*\(yes\|no\)$' /etc/ssh/sshd_config | cut -d: -f1:查找指定内容在文件中的行号
sed -i -e '61d;63d;' /etc/ssh/sshd_config:删除61和63行
sed '61i PasswordAuthentication yes' -i /etc/ssh/sshd_config:在第61行前(i:是insert,行前插入,a:是append,行后插入)插入“PasswordAuthentication yes”
————————————————
版权声明:本文为CSDN博主「bluishglc」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bluishglc/article/details/125144440
标签:配置文件,PasswordAuthentication,正则表达式,database,注释,插入,sed,yes From: https://blog.51cto.com/yimiyinei/5953775