• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

sed正则表达式的使用以和使用sed修改配置文件的典型案例

武飞扬头像
Laurence
帮助1

场景一

场景描述:找到指定的行,将其注释掉(是直接注释,不是修改值),然后紧接下一行插入新内容

这种场景在修改配置文件时最常见,注释和插入的往往是同一配置项,为了维护配置文件的可读性,通常会将关系紧密的几项配置放在一起,这就是为什么需要紧接下一行插入新内容的原因。

编辑示例:

我们现在要编辑/var/kerberos/krb5kdc/kdc.conf文件,编辑内容为:找到现有的database_name配置项将其注释掉,然后紧邻下一行插入新的配置项(因为两项配置关系密切)。

...
#database_name = /var/kerberos/krb5kdc/principal
database_module = openldap_ldapconf
...

编辑命令:

# 找到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

知识点:

这条sed语句有很多值得学习和复用的地方,总结如下:

  • ^\s*:考虑可能的缩进,增强匹配的适用性

  • \(, \), \\\|,\1,\2:注意要转义的字符

  • \1,\2:注意对分组的运用,分组的用处在于能将匹配到的内容作为一个整体“复制”到期望的位置。本例中如果只是想在database_name前加上一个#符号,是用不到分组的,这里用到分组的原因是:替换的字符串要在原字符串的基础上append新内容,这就需要将原字符串中的“缩进部分”和“database_name的后半部分”复制到替换字符串中,因此需要对这两个独立的部分进行“标记”,以便在替换字符串中“引用”

  • \n:新起一行插入内容

关于grep正则表达式有哪些字符需要转义,可参考:
https://www.gnu.org/software/findutils/manual/html_node/find_html/grep-regular-expression-syntax.html

场景二

场景描述:文件中可能有针对某一项配置的多行记录,有的是生效中的配置,有的是被注释掉的候选配置,需求是找到这些冗余的项,全部移除,然后在原第一行中插入唯一生效的项。

场景二和场景一是有区别的:场景一要注释掉的是一个确定存在且生效中的项,不存在多个注释或未注释的同名项,新插入的项也与注释掉的项不同(仅仅是关系紧密); 场景二的处理的则是可能存在多个注释或未注释的同名项,且新插入的项还是同一项,这样在判断哪些项需要注释,哪些项需要取消取消注释就会非常麻烦,所以方案二的处理策略是:全部移除,以新插入的项为准。这样会带来一个问题,一旦移除这些已有的项,就找不到合适的位置来插入新项了,所以,移除前,需要先把行号记录下来,然后在原第一行处插入,这样,可以保持配置项的上下关联性。

编辑示例:

我们现在要编辑/etc/ssh/sshd_config文件,其内容可能如下,也可能是其他状况,总之会存在多项UsePAM和PasswordAuthentication的行,有的是注释掉的,有的是生效中的:

...
UsePAM no
#UsePAM yes
...
PasswordAuthentication no
#PasswordAuthentication yes
...

我们希望编辑后是这个样子:

...
UsePAM yes
...
PasswordAuthentication yes
...

编辑命令:

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

知识点:

  • 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”

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgffcgk
系列文章
更多 icon
同类精品
更多 icon
继续加载