Назад | Перейти на главную страницу

Соответствие первому блоку текста из файла между 2 строками

Я пытаюсь соответствовать только первый блок текста между двумя строками: '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' - восстановить строку обратно на многострочный вывод