【问题标题】:use sed to in-place replace a line in a file with multiple lines from stdin or HEREDOCs使用 sed 将文件中的一行替换为来自标准输入或 HEREDOC 的多行
【发布时间】:2019-06-27 10:53:39
【问题描述】:

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

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

$ 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 中的替换,或者是否有其他方法可以做我正在寻找的事情?

【问题讨论】:

  • 请在您的问题中添加示例输入和该示例输入所需的输出。
  • 第一个代码块确实有一个使用\n的示例输入和输出。我希望实现与输入相同的输出...

标签: bash sed replace newline heredoc


【解决方案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 脚本不同,后者在给定 /s 或任何 ERE 正则表达式字符或捕获组或反向引用时会失败。 .. 在输入中(详见Is it possible to escape regex metacharacters reliably with sed)。

【讨论】:

  • 这会就地替换文件吗?
  • 不,只需将&gt; tmp &amp;&amp; mv tmp file 添加到脚本末尾即可使用sed -i 在内部执行的tmp 文件进行相同类型的伪就地编辑,或者如果您有GNU awk 添加@一开始是 987654326@,就像你在 GNU sed 中使用 -i 一样。
  • 谢谢。在弄清楚它在做什么之后,我将对其进行测试。我尝试在执行命令之前理解它们。或者,您愿意分解awk 命令中的所有内容吗?
  • 不客气。不,但是在您浏览了 awk 手册页后,我愿意回答问题(您会从中学到更多,而不是我只用勺子喂给您这个答案)。
  • 我知道 NR、FNR、条件/三元 NR &gt; 1 ? new ORS : "" 等各个部分是什么意思,但不确定放在一起意味着什么。对于第一个文件,并且只有第一个文件,将new 设置为new ORS (??) 如果NR&gt;1,然后在经过file 时,如果该行匹配"DINGO=bingo",则将其替换为@987654337 @...
【解决方案2】:

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

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

这会将以DINGO 开头的行替换为在 sed 命令中作为文件传送到标准输入的 here-document。

另一种选择:

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

注意在替代解决方案中,here-doc 只会被读取一次!

【讨论】:

  • 这太棒了! /r 和 //d 是什么意思?我在手册页中找不到对它的引用。
  • @IMTheNachoMan /r file 读取file 的内容并将其附加到当前行之后。 //d 重复最后一个正则表达式并删除该行。要插入文件,请参阅我的替代方案,这允许修改当前行。
猜你喜欢
  • 2013-04-16
  • 2019-03-24
  • 1970-01-01
  • 2014-06-29
  • 2017-11-08
  • 1970-01-01
  • 2014-02-03
  • 2012-01-28
  • 2011-02-19
相关资源
最近更新 更多