使用 sed 就地用标准输入或 HEREDOC 中的多行替换文件中的一行

use sed to in-place replace a line in a file with multiple lines from stdin or HEREDOCs

我想用多行替换文件中的一行。我知道我可以在 sed 替换中使用 \n,但这相当难看。我希望听到 HEARDOC。

所以我可以这样做来用多行替换该行:

$ cat sedtest
DINGO=bingo

$ sed -i -e "s/^DINGO.*$/# added by $(whoami) on $(date)\nDINGO=howdy/" sedtest

$ cat sedtest
# added by user on Sun Feb  3 08:55:44 EST 2019
DINGO=howdy

在命令中,我想将替换内容换行,这样更容易 read/understand。到目前为止,当我想向文件 添加 新行时,我一直在使用 HEREDOC:

CAT << EOF | sudo tee -a file1 file2 file3
line one
line two
line three
EOF

这对 appending/adding 很有效。是否可以做类似的事情,而是使用输出作为 sed 中的替代品,或者是否有其他方法可以做我正在寻找的事情?

这是你想要做的吗?

$ awk 'NR==FNR{new=(NR>1?new ORS:"") [=10=];next} [=10=]=="DINGO=bingo"{[=10=]=new} 1' - file <<!
# added by $(whoami) on $(date)
DINGO=howdy
!
# added by user on Sun, Feb  3, 2019  8:50:41 AM
DINGO=howdy

请注意,上面使用的是文字字符串操作,因此它适用于旧字符串或新字符串中的任何字符,这与您的 sed 脚本不同,后者在给定 /s 或任何 ERE 正则表达式字符或捕获组时会失败或反向引用或...在输入中(有关详细信息,请参阅 )。

这可能适合您 (GNU sed):

cat <<! | sed -i -e '/^DINGO/r /dev/stdin' -e '//d' file
# added by $(whoami) on $(date)
DINGO=howdy
!

这会将 DINGO 开头的行替换为 here-document,该文档作为 sed 命令中的文件通过管道传输到 stdin。

备选方案:

cat <<! | sed -i -e '/^DINGO/e cat /dev/stdin' -e 's/bingo/howdy' file
# added by $(whoami) on $(date)
!

N.B。在替代解决方案中,here-doc 将只被阅读一次!