AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 737099
Accepted
yael
yael
Asked: 2023-02-28 00:00:40 +0800 CST2023-02-28 00:00:40 +0800 CST 2023-02-28 00:00:40 +0800 CST

如何从 fstab 中删除所有 UUID 但不删除引导文件系统的 UUID

  • 772

在下面的示例fstab文件中,我们要删除所有以 开头的行UUID,但除了UUID带有bootword的行

/dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
/dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0


UUID=0b14011d-f69d-4c4c-8ce0-6240bb0a574a   /var/kafka/mp1                      xfs defaults,noatime 0 0
UUID=2d7872f2-96d4-4ba9-8a17-a1115542645c   /var/kafka/mp2                      xfs defaults,noatime 0 0
UUID=79bdbf56-9a09-4505-ab8e-41ce9432cf0f   /var/kafka/mp3                      xfs defaults,noatime 0 0
UUID=ca42a388-83d4-4f8b-aff7-3450d836eef7   /var/kafka/mp4                      xfs defaults,noatime 0 0
UUID=62d356bb-c393-4a74-bbf9-984b60d3b5c4   /var/kafka/mp5                      xfs defaults,noatime 0 0
UUID=d4071a83-204f-475f-8917-cdd77ef6b1ed   /var/kafka/mp6                      xfs defaults,noatime 0 0

所以例外的结果应该如下

/dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
/dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0

到目前为止,我们有以下 sed

 sed -i '/^UUID/d'  /etc/fstab

但是上面的方法删除了所有UUID行

text-processing
  • 6 6 个回答
  • 853 Views

6 个回答

  • Voted
  1. Stéphane Chazelas
    2023-02-28T14:51:48+08:002023-02-28T14:51:48+08:00

    在我看来,您想删除第一个字段以开头UUID=而第二个字段不是的行/boot。

    Soawk或 perl 的 awk 模式似乎是一个显而易见的选择:

    awk '! ($1 ~ /^UUID=/ && $2 != "/boot")' /etc/fstab
    

    (GNU awk 可以使用 就地编辑-i inplace)。

    perl -lae 'print unless $F[0] =~ /^UUID=/ && $F[1] ne "/boot"' /etc/fstab
    

    (perl有-i就地编辑)。

    等效项可以通过以下方式完成sed:

    sed '/^[[:space:]]*[^[:space:]]\{1,\}[[:space:]]\{1,\}/boot\([[:space:]].*\)\{0,1\}$/b
         /^[[:space:]]*UUID=/d' /etc/fstab
    

    有些s 可以使用(大多数)或(FreeBSD 和包括 macos 在内的衍生产品)sed进行就地编辑。-i-i ''

    • 6
  2. meuh
    2023-02-28T00:15:50+08:002023-02-28T00:15:50+08:00

    有很多可能性。保持简单你可以使用

    '/^UUID/{
       /\/boot/b
       d
    }'
    

    {}当模式匹配时,它用于包含更多要执行的命令。如果引导匹配,b分支到命令的末尾,否则d完成。或者,

    '/^UUID/{
       /\/boot/!d
    }'
    

    如果引导不匹配,则删除。这些模式应该通过匹配空格来增强,但如果您了解文件中的预期内容,您可能并不关心。

    单行版本可能不适用于某些版本sed:

    '/^UUID/{/\/boot/b;d;}'
    

    和

    '/^UUID/{/\/boot/!d;}'
    
    • 4
  3. Best Answer
    ralz
    2023-02-28T00:22:19+08:002023-02-28T00:22:19+08:00

    首先告诉 sed 打印包含 的行boot,然后告诉它删除包含UUID, 分隔表达式的行;

    sed -i '/boot/p;/UUID/d' /etc/fstab
    

    由于 print 表达式在 delete 表达式之前给出,包含 boot 的行将被打印,在删除带有 UUID 的行之前,如果您要更改表达式位置,这是行不通的。

    鉴于你给出的例子,你应该得到这样的东西

    /dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
    UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
    /dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0
    

    ^您还可以添加删除空行、标记行首和$标记行尾的部分,因此添加表达式以删除$行尾紧跟在行首之后的行^。

    sed -i '/boot/p;/UUID/d;/^$/d' /etc/fstab
    


    编辑

    正如 Stéphane Chazelas 在评论中指出的那样,如果同一行中不包含 UUID,这将打印包含 boot 的行两次,所以这样的事情会更好。

    sed -i '/^UUID/{/boot/!d};/^$/d' /etc/fstab
    

    它将删除以 UUID 开头的行,除非它们包含 /boot,然后删除所有空行

    • 4
  4. Gilles Quénot
    2023-02-28T00:15:49+08:002023-02-28T00:15:49+08:00

    使用perl:

    perl -i -pe 's@^UUID\S+\s++(?!/boot).*\n@@' /etc/fstab
    

    -i中的相似,sed在线替换

    正则表达式匹配如下:

    节点 解释
    ^ 字符串的开头
    UUID 'UUID'
    \S+ 非空白(除了 \n、\r、\t、\f 和 " ")(1 次或多次(匹配尽可能多的数量))
    \s++ whitespace (\n, \r, \t, \f, and " ") 匹配 1 次或多次并且不返回任何内容
    (?! 往前看有没有:
    /boot '/引导'
    ) 先行结束
    .* 除 \n 之外的任何字符(0 次或更多次(匹配尽可能多的数量))
    \n '\n'(换行符)
    • 2
  5. terdon
    2023-02-28T01:19:32+08:002023-02-28T01:19:32+08:00

    我自己会在 awk 中执行此操作,因为当某项计算结果为真时,我们可以利用默认操作打印该行。所以我们需要做的就是测试这一行是匹配boot还是不匹配UUID:

    $ awk '/boot/ || !/UUID/' file 
    /dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
    UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
    /dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0
    
    
    

    您还可以删除空行:

    $ awk '/./ && (/boot/ || !/UUID/)' file 
    /dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
    UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
    /dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0
    

    /boot您可以通过确保匹配并作为单个“单词”来使它更安全一些,并且它UUID位于行的开头,然后是=:

    awk '/./ && (/\/boot\>/ || !/^UUID=/)' file 
    

    而且,使用 GNU awk,您可以使用它-i inplace来编辑原始文件,就像sed:

    gawk -i inplace '/./ && (/boot/ || !/UUID/)' file 
    

    如果您绝对必须使用sed,这里还有另一种方法:

    $ sed -n '/\/boot/p; /UUID/!p' file
    /dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
    UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
    /dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0
    
    
    

    关闭-n行打印,然后我们打印 ( p) 如果行匹配/boot或不匹配UUID(!p末尾的/UUID/!p意思是“如果不匹配则打印”)。

    最后,这是另一种 perl 方法:

    $ perl -ne 'print if /\/boot/ || !/UUID/ ' file
    /dev/mapper/VG100-lv_root /                       xfs     defaults        0 0
    UUID=735cb76a-51b5-4e06-b6fb-3b9577e38dc5 /boot                   xfs     defaults        0 0
    /dev/mapper/VG100-lv_var /var                    xfs     defaults        0 0
    
    
    
    • 2
  6. Shadur
    2023-02-28T20:39:07+08:002023-02-28T20:39:07+08:00

    我怎么强调都不为过:您不想使用 sed 脚本执行此操作。

    改用类似 Ansible 的东西。

    只需快速阅读其模块的文档mount,您就会发现您可以使用以下内容为整个 2500 多个系统集群自动化它:

    name: Remove kafka1 mount
      ansible.posix.mount:
        backup: true
        path: '/var/kafka/{{ item }}'
        state: absent
      loop:
        - 'mp1'
        - 'mp2'
        - 'mp3' 
    

    这会

    1. 避免需要精心挑选的模式匹配,这可能适用于所有情况,也可能不适用于所有情况;
    2. 让您只需调用一次即可在所有系统上运行脚本,避免重复工作造成的错别字
    3. 生成您的 fstab 条目的备份,如果您发现遗漏了某些内容,您将能够从中恢复
    4. 允许您在运行脚本之前进行测试,并可能导致 2000 多个系统无法使用。
    • 2

相关问题

  • grep 从 $START 到 $END 的一组行并且在 $MIDDLE 中包含匹配项

  • 重新排列字母并比较两个单词

  • 在awk中的两行之间减去相同的列

  • 多行文件洗牌

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve