这个 sed end-case 没有意义,我不知道为什么

This sed end-case doesn't make sense, and I don't know why

我发现以下 sed end-case 没有意义,但我不知道为什么,我无法进一步简化它。

基本上我想更改一行并删除一系列行,如下所示:

$ seq 9 | sed '/3/s/$/==/; /4/,/6/d;'
1
2
3==
7
8
9

但是,当涉及到以下实际代码时,我想更改一行并删除一系列行,它不再对我有用(如果我取消注释第一个命令):

$ cat ./grub2clean.why-0.sed
#/menuentry/{ s/^/\n/; s/--\(class\|id\) .*$/\{/ };

# WHY?!
/Ubuntu/s/Ubuntu/UUUU/;
/^submenu /,/^}/d;
/UUUU/s/UUUU/!Ubuntu/;

我是运行:

sed -f ./grub2clean.why-0.sed grub.test.cfg

如果我取消对第一个命令的注释,则位于两个工作替换中间的 delete-a-range-of-lines 命令将不再有效。

这太~~~~奇怪,我也不知道为什么。

拜托,请有人帮忙!

grub.test.cfg 文件是:

more here
menuentry 'Ubuntu 20.04 LTS (20.04) (on /dev/sda3)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-dcf03c24-3d0d-4581-be1d-67b90f92a2c1' {
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt3'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt3 --hint-efi=hd0,gpt3 --hint-baremetal=ahci0,gpt3  dcf03c24-3d0d-4581-be1d-67b90f92a2c1
        else
          search --no-floppy --fs-uuid --set=root dcf03c24-3d0d-4581-be1d-67b90f92a2c1
        fi
        linux /boot/vmlinuz-5.4.0-33-generic root=UUID=dcf03c24-3d0d-4581-be1d-67b90f92a2c1 ro net.ifnames=0
        initrd /boot/initrd.img-5.4.0-33-generic
}
submenu 'Advanced options for Ubuntu 20.04 LTS (20.04) (on /dev/sda3)' $menuentry_id_option 'osprober-gnulinux-advanced-dcf03c24-3d0d-4581-be1d-67b90f92a2c1' {
        menuentry 'Ubuntu (on /dev/sda3)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/boot/vmlinuz-5.4.0-33-generic--dcf03c24-3d0d-4581-be1d-67b90f92a2c1' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt3'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt3 --hint-efi=hd0,gpt3 --hint-baremetal=ahci0,gpt3  dcf03c24-3d0d-4581-be1d-67b90f92a2c1
                else
                  search --no-floppy --fs-uuid --set=root dcf03c24-3d0d-4581-be1d-67b90f92a2c1
                fi
                linux /boot/vmlinuz-5.4.0-33-generic root=UUID=dcf03c24-3d0d-4581-be1d-67b90f92a2c1 ro net.ifnames=0
                initrd /boot/initrd.img-5.4.0-33-generic
        }
        menuentry 'Ubuntu, with Linux 5.4.0-33-generic (recovery mode) (on /dev/sda3)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/boot/vmlinuz-5.4.0-33-generic-root=UUID=dcf03c24-3d0d-4581-be1d-67b90f92a2c1 ro recovery nomodeset-dcf03c24-3d0d-4581-be1d-67b90f92a2c1' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt3'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt3 --hint-efi=hd0,gpt3 --hint-baremetal=ahci0,gpt3  dcf03c24-3d0d-4581-be1d-67b90f92a2c1
                else
                  search --no-floppy --fs-uuid --set=root dcf03c24-3d0d-4581-be1d-67b90f92a2c1
                fi
                linux /boot/vmlinuz-5.4.0-33-generic root=UUID=dcf03c24-3d0d-4581-be1d-67b90f92a2c1 ro recovery nomodeset
                initrd /boot/initrd.img-5.4.0-33-generic
        }
}

menuentry 'Ubuntu 19.04 (19.04) (on /dev/sda7)' --class ubuntu --class gnu-linux -
-class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-db9e32bf-a209
-453f-9eb9-82123fc46652' {
        insmod part_gpt
        insmod ext2
        set root='hd0,gpt7'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt7 --hint-efi=
hd0,gpt7 --hint-baremetal=ahci0,gpt7  db9e32bf-a209-453f-9eb9-82123fc46652
        else
          search --no-floppy --fs-uuid --set=root db9e32bf-a209-453f-9eb9-82123fc46652
        fi
        linux /vmlinuz root=/dev/sda7
        initrd /initrd.img
}
submenu 'Advanced options for Ubuntu 19.04 (19.04) (on /dev/sda7)' $menuentry_id_option 'osprober-gnulinux-advanced-db9e32bf-a209-453f-9eb9-82123fc46652' {
        menuentry 'Ubuntu 19.04 (19.04) (on /dev/sda7)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz--db9e32bf-a209-453f-9eb9-82123fc46652' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt7'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt7 --hint-efi=hd0,gpt7 --hint-baremetal=ahci0,gpt7  db9e32bf-a209-453f-9eb9-82123fc46652
                else
                  search --no-floppy --fs-uuid --set=root db9e32bf-a209-453f-9eb9-82123fc46652
                fi
                linux /vmlinuz root=/dev/sda7
                initrd /initrd.img
        }
        menuentry 'Ubuntu 19.04 (19.04) (on /dev/sda7)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz--db9e32bf-a209-453f-9eb9-82123fc46652' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt7'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt7 --hint-efi=hd0,gpt7 --hint-baremetal=ahci0,gpt7  db9e32bf-a209-453f-9eb9-82123fc46652
                else
                  search --no-floppy --fs-uuid --set=root db9e32bf-a209-453f-9eb9-82123fc46652
                fi
                linux /vmlinuz root=/dev/sda7
                initrd /initrd.img
        }
        menuentry 'Ubuntu 19.04 (19.04) (on /dev/sda7)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz--db9e32bf-a209-453f-9eb9-82123fc46652' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt7'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt7 --hint-efi=hd0,gpt7 --hint-baremetal=ahci0,gpt7  db9e32bf-a209-453f-9eb9-82123fc46652
                else
                  search --no-floppy --fs-uuid --set=root db9e32bf-a209-453f-9eb9-82123fc46652
                fi
                linux /vmlinuz root=/dev/sda7
                initrd /initrd.img.old
        }
        menuentry 'Ubuntu 19.04 (19.04) (on /dev/sda7)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz.old--db9e32bf-a209-453f-9eb9-82123fc46652' {
                insmod part_gpt
                insmod ext2
                set root='hd0,gpt7'
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt7 --hint-efi=hd0,gpt7 --hint-baremetal=ahci0,gpt7  db9e32bf-a209-453f-9eb9-82123fc46652
                else
                  search --no-floppy --fs-uuid --set=root db9e32bf-a209-453f-9eb9-82123fc46652
                fi
                linux /vmlinuz.old root=/dev/sda7
                initrd /initrd.img.old
        }
}

more here

在以下两个操作系统下测试,

$ lsb_release -a 
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux bullseye/sid
Release:        10.10
Codename:       buster

$ lsb_release -a 
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04 LTS
Release:        20.04
Codename:       focal

$ sed --version
sed (GNU sed) 4.7
...

$ apt-cache policy sed
sed:
  Installed: 4.7-1
  Candidate: 4.7-1
  Version table:
 *** 4.7-1 500
        500 http://archive.ubuntu.com/ubuntu focal/main amd64 Packages
        100 /var/lib/dpkg/status

在您的第一个 sed 命令中,您查找任何包含 menuentry 的行并将换行符作为该行的第一个字符。

然后在删除命令中,范围从以submenu开始的行到以右大括号开始的行。

当脚本在包含 menuentry 的任何行的第一个字符中放置一个换行符时,它还会将一个作为以 submenu 开头的行的第一个字符,因为这些行也包含 menuentry$menuentry_id_option 位中。

所以在第一个 sed 命令之后,没有任何以 submenu 开头的行 - 所有这些行现在都以换行符开头。

因此,您的第一个 sed 命令应该只匹配以 menuentry 开头且带有可选前导空格的行,或者 delete 命令应该查找以换行符开头后跟 submenu 的行。