sed 用于多行选择和删除

sed 用于多行选择和删除

给定输入格式为

        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

. . .

 if test x$grub_platform = xpc; then
   linux_suffix=16; 
 else
   linux_suffix= ; 
 fi

更新:

我一开始没说清楚。问题grub2 的 feature_platform_search_hint 何时可能为“No”有更多信息。即,还有其他 if 语句,而我只想处理其中feature_platform_search_hint一个。现在再放一个if案例在上面。

我希望我在忽略/删除整个命令块的情况下sed选择第一个命令:searchfeature_platform_search_hintif

        set root='hd0,gpt3'
        search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt3 --hint-efi=hd0,gpt3 --hint-baremetal=ahci0,gpt3  dcf03c24-3d0d-4581-be1d-67b90f92a2c1
        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

其余/剩余线路完好无损。

这是sed我想出的命令:

/feature_platform_search_hint/{
# remove if line and keep next
d; N; h;
# remove else block
N; N; N; d;
g; s/  search /search /;
}

但它没有按我的预期工作。
为什么以及如何解决?谢谢

答案1

sed '/^ *if \+/d;/^ *else *$/,/^ *fi *$/d' remove_if_block

/^ *if
在上面的行中,您有空格,因此“if”之前有空格和星号。
我不知道你的文件是否真的有它们。但即使有它们,上面的代码也应该可以工作。如果有人无意中在“else”和“fi”后面添加空格,
else *$/fi *$
在“else”和“fi”之后添加空格以提供保护...也可以以以下方式开头别处, 所以...

答案2

只需将if语句替换为if true; then即可创建具有相同效果的 shell 代码。

sed 's/^ *if \[.*]; then/if true; then # &/' file

这替换了该if语句,但在注释中保留了原始代码。

答案3

找到了我的解决方案——无法使用d,它将立即开始下一个周期,而其余命令不被处理。

# input:
$ seq 9
1
2
3
4
5
6
7
8
9

# goal: remove line 4 (if), and 6~8 (3-line else block)

$ seq 9 | sed '/4/{N; s/^.*\n//; h; N; N; N; g; }'
1
2
3
5
9

相关内容