![sed 将文本放置在特定行之后](https://linux22.com/image/115220/sed%20%E5%B0%86%E6%96%87%E6%9C%AC%E6%94%BE%E7%BD%AE%E5%9C%A8%E7%89%B9%E5%AE%9A%E8%A1%8C%E4%B9%8B%E5%90%8E.png)
我通读了 Sed 的联机帮助页,但仍然觉得它很混乱,所以我希望在这里找到一些答案:)
我需要使用 bash 脚本编辑文件。
我需要在 grub.cfg 中的特定行之后放置几行。为了展示示例,我将新添加 5 行。
原来的:
if loadfont /boot/grub/font.pf2 ; then
set gfxmode=auto
insmod efi_gop
insmod efi_uga
insmod gfxterm
terminal_output gfxterm
fi
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
menuentry "Install Ubuntu Server" {
set gfxpayload=keep
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed quiet ---
initrd /install/initrd.gz
}
menuentry "OEM install (for manufacturers)" {
set gfxpayload=keep
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed quiet oem-config/enable=true ---
initrd /install/initrd.gz
}
编辑后:
if loadfont /boot/grub/font.pf2 ; then
set gfxmode=auto
insmod efi_gop
insmod efi_uga
insmod gfxterm
terminal_output gfxterm
fi
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
newly_addedd_line_1
newly_addedd_line_2
newly_addedd_line_3
newly_addedd_line_4
newly_addedd_line_5
menuentry "Install Ubuntu Server" {
set gfxpayload=keep
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed quiet ---
initrd /install/initrd.gz
}
menuentry "OEM install (for manufacturers)" {
set gfxpayload=keep
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed quiet oem-config/enable=true ---
initrd /install/initrd.gz
}
使用 sed 会如何工作?理想情况下,我会将所有新行放在新的脚本变量中。
例如:
LINES_TO_ADD='newly_addedd_line_1\n
newly_addedd_line_2\n
newly_addedd_line_3\n
newly_addedd_line_4\n
newly_addedd_line_5'
先感谢您!
答案1
sed '/^set menu_color_highlight/a\
newly_addedd_line_2\
newly_addedd_line_3\
newly_addedd_line_4\
newly_addedd_line_5' /path/to/file
验证输出后,您可以使用sed --in-place
或写入新文件并交换旧版本。
从手册:
[1addr]a\ text Write text to standard output immediately before each attempt to read a line of input, whether by executing the ``N'' function or by beginning a new cycle.
可能稍微更稳健一些,您可以将新的文本块放入文件中(例如newlines
),然后使用:
sed '^set menu_color_highlight/r newlines' /path/to/input.
再次,来自手册:
[1addr]r file Copy the contents of file to the standard output immediately before the next attempt to read a line of input. If file cannot be read for any reason, it is silently ignored and no error condition is set.
答案2
LINES_TO_ADD='newly_addedd_line_1
newly_addedd_line_2
newly_addedd_line_3
newly_addedd_line_4
newly_addedd_line_5'
LINES_TO_ADD_ESC=$(printf '%s\n' "$LINES_TO_ADD" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed -e "
/^set menu_color_highlight=/G
//s/\$/$LINES_TO_ADD_ESC/
"
答案3
如果特定的行号永远不会改变,那么您可以使用类似以下内容的内容:
sed -i '11inewly_addedd_line_1 \
newly_addedd_line_2 \
newly_addedd_line_3 \
newly_addedd_line_4 \
newly_addedd_line_5' /path/to/your/grub.cfg
您可以通过不包含“-i”标志来仔细检查它是否会首先执行您想要的操作(如果没有它,这将打印出包含您的更改的文件,但实际上不会更改该文件)。
如果您想在模式匹配之后添加它并且您要放入的模式包含整行,那么您可以这样做:
sed -i '/set menu_color_highlight=black\/light-gray/a \
newly_addedd_line_1 \
newly_addedd_line_2 \
newly_addedd_line_3 \
newly_addedd_line_4 \
newly_addedd_line_5' /path/to/your/grub.cfg
其中 /PATTERN/a 表示追加到模式之后。
您还可以在使用 /PATTERN/i 插入的行之前添加内容。