使用 sed 将多行连续行替换为一行

使用 sed 将多行连续行替换为一行

在我所有的 python 脚本中,我想替换连续的两行

import matplotlib as mpl
mpl.style.use(mpl_plt_default_template)

只用这条线

plt.style.use(mpl_plt_default_template)

到目前为止,我已经找到了离开将连续两行替换为应用于每一行的表达式,但不介绍如何将这两行完全替换为一行。关于我不成功的方法,它应用了以下 sed 字符串:

sed '/import matplotlib as mpl$/N;//s/mpl.style.use(mpl_plt_default_template)/plt.style.use(mpl_plt_default_template)/g'

笔记第一行(import matplotlib as mpl ) 也可以出现在文件的其他位置并且应该保持不变,因此目标是仅当发现两行按照给定顺序依次出现时才执行替换。

编辑涉及以下的附加范围find

find最终目标是使用类似于以下方式的管道替换通过 - 命令找到的多个文本文件中的这两行:

find /path/to/dir/ -type f -exec sed 'old-lines/s/single-new-line' {} \;

系统细节:

操作系统:Lubuntu 20.04 LTS

答案1

要编辑文件,请使用可编写脚本的文本编辑器,例如埃德或者前任(都是 POSIX 编辑器)。语法非常相似。

printf '%s\n' '/^import matplotlib as mpl$/d' 's/mpl/plt' 'w' 'q' | ed -s file
printf '%s\n' '/^import matplotlib as mpl$/d' 's/mpl/plt' 'x' | ex file
  • printf '%s\n'向编辑器提供命令。

  • /^import matplotlib as mpl$/d删除与模式匹配的第一行。

  • s/mpl/plt在下一行执行替换。

  • wq/或x保存更改。

如果你真的想要 Sed,

sed '/^import matplotlib as mpl$/N; s/.*\nmpl/plt/' file

解决您的扩展问题:

find /path/to/dir/ -type f -exec sh -c '
    printf "%s\n" "/^import matplotlib as mpl\$/d" "s/mpl/plt" "w" "q" |
    ed -s "$1"' sh {} \;

答案2

如果不需要sed,您可以用于awk该任务:

awk '$0=="import matplotlib as mpl" {buf=$0; next}
     buf {if (/^mpl\.style\.use/) {sub(/^mpl/,"plt")} else {print buf}; buf=""} 1' inputfile
  • 当遇到精确读取的行时import matplotlib as mpl,它将把它存储在缓冲区中buf并跳到下一行执行。
  • 如果设置了缓冲区变量,并且当前行以 开头mpl.style.use,它将替换当前行的该部分plt.style.use并丢弃缓冲区内容。
  • 如果设置了缓冲区变量,但当前行与“第二行”模式不匹配,则会在打印当前行之前打印缓冲区内容。然后缓冲区被清除。
  • 对于缓冲区为空时遇到的所有行,我们只需按原样打印该行。

如果您需要第二行的更精确匹配,请将第二条规则更改为

buf {if ($0=="mpl.style.use(mpl_plt_default_template)" {sub(/^mpl/,"plt")} else {print buf}; buf=""}

相关内容