Bash

匹配文件中的第一個文本塊,在 2 個字元串之間

  • February 15, 2016

我試圖只匹配兩個字元串之間的第一個文本塊:‘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表示“如果該行與模式匹配/^\}$/則退出”

這適用於我使用多次通行證

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'- 將字元串恢復為多行輸出

引用自:https://serverfault.com/questions/757221