使用sed将文件中的一行替换为stdin或HEREDOC中的多行

时间:2019-02-03 13:58:12

标签: bash sed replace newline heredoc

我想用多行替换文件中的一行。我知道我可以在\n替换中使用sed,但这很丑陋。我希望有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

在命令中,我要将替换内容放在新行中,以便于阅读/理解。到目前为止,当我要添加新行到文件中时,我一直在使用HEREDOC:

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

这对于附加/添加非常有效。是否可以执行类似的操作,而是将输出用作sed中的替换内容,或者是否有其他方法可以完成我正在寻找的工作?

2 个答案:

答案 0 :(得分:1)

这是您要做什么吗?

$ awk 'NR==FNR{new=(NR>1?new ORS:"") $0;next} $0=="DINGO=bingo"{$0=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脚本不同,后者会在给定/或任何ERE regexp字符或捕获组或反向引用的情况下失败或...输入中(有关详细信息,请参见Is it possible to escape regex metacharacters reliably with sed)。

答案 1 :(得分:1)

这可能对您有用(GNU sed):

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

这将用此处文档替换DINGO开头的行,并在sed命令中作为文件通过管道传给stdin。

替代方法:

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

在替代解决方案中,此处文档只能读取一次!