如何通过匹配整行来取消注释和注释 /etc/fstab 中的行?

如何通过匹配整行来取消注释和注释 /etc/fstab 中的行?

我的 /etc/fstab 文件中有以下几行:

#
# /etc/fstab
# Created by anaconda on Sun Aug 23 14:32:22 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rootvg-rootlv /                       xfs     defaults        0 0
UUID=af74c8xz-e6ec-2387-b2xe-cdc32519a69f /boot                   xfs     defaults        0 0
UUID=GH4E-B04C          /boot/efi               vfat    defaults,uid=0,gid=0,umask=0077,shortname=winnt 0 0
#/dev/mapper/rootvg-homelv /home                   xfs     defaults        0 0
/dev/mapper/rootvg-optlv /opt                    xfs     defaults        0 0
#/dev/mapper/rootvg-tmplv /tmp                    xfs     defaults        0 0
/dev/mapper/rootvg-usrlv /usr                    xfs     defaults        0 0
/dev/mapper/rootvg-varlv /var                    xfs     defaults        0 0
/dev/mapper/rootvg-homelv /home                   xfs    nodev        1 2
/dev/mapper/rootvg-tmplv /tmp                    xfs    defaults,nodev,nosuid,noexec        1 2
tmpfs /dev/shm tmpfs nodev,nosuid,noexec 0 0
UUID=34g5et-fg55-40er-bx8u-9fhe47f986ab   /datadisk   ext4   defaults,nofail   1   2
/dev/disk/cloud/azure_resource-part1    /mnt    auto    defaults,nofail,x-systemd.requires=cloud-init.service,comment=cloudconfig       0       2

/home和有两个条目/tmp。我需要取消注释/home/tmp并注释掉其他/home/tmp行。

所以,我的最终文件应该如下所示:

#
# /etc/fstab
# Created by anaconda on Sun Aug 23 14:32:22 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rootvg-rootlv /                       xfs     defaults        0 0
UUID=af74c8xz-e6ec-2387-b2xe-cdc32519a69f /boot                   xfs     defaults        0 0
UUID=GH4E-B04C          /boot/efi               vfat    defaults,uid=0,gid=0,umask=0077,shortname=winnt 0 0
/dev/mapper/rootvg-homelv /home                   xfs     defaults        0 0
/dev/mapper/rootvg-optlv /opt                    xfs     defaults        0 0
/dev/mapper/rootvg-tmplv /tmp                    xfs     defaults        0 0
/dev/mapper/rootvg-usrlv /usr                    xfs     defaults        0 0
/dev/mapper/rootvg-varlv /var                    xfs     defaults        0 0
#/dev/mapper/rootvg-homelv /home                   xfs    nodev        1 2
#/dev/mapper/rootvg-tmplv /tmp                    xfs    defaults,nodev,nosuid,noexec        1 2
tmpfs /dev/shm tmpfs nodev,nosuid,noexec 0 0
UUID=34g5et-fg55-40er-bx8u-9fhe47f986ab   /datadisk   ext4   defaults,nofail   1   2
/dev/disk/cloud/azure_resource-part1    /mnt    auto    defaults,nofail,x-systemd.requires=cloud-init.service,comment=cloudconfig       0       2

我尝试了以下两个命令,但它注释的行数超出了我需要的行数,因为它找到了更多匹配项,特别是对于第二个sed命令。

sed -i '/defaults,nodev,nosuid,noexec/ s/^/#/' /etc/fstab
sed -i '/nodev/ s/^/#/' /etc/fstab

如何实现这一目标?

答案1

GNU Sed 方法,

sed -Ei '/home|tmp/{s/^#//;t;s/^/#/}' file
  • /home|tmp/如果行匹配hometmp,
    • {s/^#//;t;s/^/#/}#在行开始处删除。如果不存在,请替换以 开头的行#

Awk 的替代方案

awk '$2 ~ /home|tmp/{ if (!( sub(/^#/, "") )) $1="#"$1} 1' file
  • $2 ~ /(home|tmp)/如果第二个字段包含hometmp
    • if (!( sub(/^#/, "") ))尝试#在行开头匹配 a 并将其删除。如果操作不成功(因为#行中 没有start),
      • $1="#"$1将 a 附加#到行开头。
  • 1打印结果行。

如果您有 Gawk,则可以添加标志-i inplace来就地编辑文件,但我发现最好将输出重定向到文件,然后在检查一切正常后覆盖原始文件。

答案2

使用 ansible 模块 lineinfile 特别是如果您必须为多个主机执行此操作:https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html

相关内容