我正在尝试匹配只有第一个两个字符串“menuentry”和“}”之间的文本块来自如下文件:
输入文件:
(some irrelevant text)
menuentry 'My Customized Linux, with Linux 3.10.0-229.14.1.el7.x86_64' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-229.14.1.el7.x86_64-advanced-/dev/mapper/sysvg-lv_root' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-3.10.0-229.14.1.el7.x86_64 root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-229.14.1.el7.x86_64.img
}
menuentry 'My Customized Linux (Rescue)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db-advanced-/dev/mapper/sysvg-lv_root' {
load_video
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet
initrd16 /initramfs-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db.img
}
(some more irrelevant text)
输出应该是:
menuentry 'My Customized Linux, with Linux 3.10.0-229.14.1.el7.x86_64' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-229.14.1.el7.x86_64-advanced-/dev/mapper/sysvg-lv_root' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-3.10.0-229.14.1.el7.x86_64 root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-229.14.1.el7.x86_64.img
}
我使用 sed 来实现这一点,如下所示:
sed -n '/^menuentry /,/^}$/p;' /boot/grub2/grub.cfg
但始终获取第一个“menuentry”和最后一个“}”之间的整个文本
[root@ball ~]# sed -n '/^menuentry /,/^}$/p;' /boot/grub2/grub.cfg
menuentry 'My Customized Linux, with Linux 3.10.0-229.14.1.el7.x86_64' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-229.14.1.el7.x86_64-advanced-/dev/mapper/sysvg-lv_root' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-3.10.0-229.14.1.el7.x86_64 root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-229.14.1.el7.x86_64.img
}
menuentry 'My Customized Linux (Rescue)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db-advanced-/dev/mapper/sysvg-lv_root' {
load_video
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet
initrd16 /initramfs-0-rescue-2e4c8e37e48347b0b4fa7095fbd707db.img
}
有任何想法吗?
答案1
一行 sed
sed -n '/^menuentry/,/\}$/{p;/^\}$/q}'
/^\}$/q
表示“如果该行与模式匹配/^\}$/
则退出”
答案2
这对我来说可以使用多次传递
sed -n '/^menuentry /,$p' /boot/grub2/grub.cfg | tr '\n' '~' | sed 's/~menuentry.*//' | tr '~' '\n'
解释
sed -n '/^menuentry /,$p' /boot/grub2/grub.cfg
- 删除文件头部直到第一个menuentry
tr '\n' '~'
- 将输出转换为单行sed 's/~menuentry.*//'
- 使用 sed 删除从\nmenuentry
(现在是~menuentry
)到字符串末尾的部分tr '~' '\n'
- 将字符串恢复为多行输出
答案3
如果 Perl 可以做到...
perl -lne '$p=1 if(/^menuentry/);print if $p;exit if (/^}$/)' /boot/grub2/grub.cfg
给出
menuentry 'My Customized Linux, with Linux 3.10.0-229.14.1.el7.x86_64' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-229.14.1.el7.x86_64-advanced-/dev/mapper/sysvg-lv_root' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 2e420275-8578-449d-9217-ce6d9ae35f70
else
search --no-floppy --fs-uuid --set=root 2e420275-8578-449d-9217-ce6d9ae35f70
fi
linux16 /vmlinuz-3.10.0-229.14.1.el7.x86_64 root=/dev/mapper/sysvg-lv_root ro nomodeset rd.lvm.lv=sysvg/lv_swap vconsole.keymap=us rd.lvm.lv=sysvg/lv_root vconsole.font=latarcyrheb-sun16 rootfstype=xfs crashkernel=auto quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-229.14.1.el7.x86_64.img
}
或这个:
perl -lne 'BEGIN{$/="\nmenuentry "};if($.==2){print $/,$_;last}' /boot/grub2/grub.cfg
(此版本将 perl 行分割设置为以 menuentry 行的开始结束,然后打印您实际上想要的“第二”节。