Я пытаюсь соответствовать только первый блок текста между двумя строками: '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
}
Любые идеи?
одна строка sed
sed -n '/^menuentry/,/\}$/{p;/^\}$/q}'
/^\}$/q
означает, что "если строка соответствует шаблону /^\}$/
затем выйти "
Если 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 так, чтобы оно заканчивалось началом строки меню, затем печатает «вторую» строфу, которая на самом деле является той, которую вы хотите.
Это работает для меня с использованием нескольких проходов
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'
- восстановить строку обратно на многострочный вывод