这个 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
的行。
我发现以下 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
的行。