複数行の選択と削除のための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ステートメントがあり、そのうちの1つだけを処理したいと思います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

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

関連情報