如何用sed替换多行代码?


9

我有一个很大的文件,里面有特殊字符。那里有一个多行代码,我想替换为sed

这个:

  text = "\
    ------                                                           ------\n\n\
    This message was automatically generated by email software\n\
    The delivery of your message has not been affected.\n\n\
    ------                                                           ------\n\n"

需要变成这样:

text = ""

我尝试了以下代码,但没有运气:

sed -i '/  text = "*/ {N; s/  text = .*affected.\./  text = ""/g}' /etc/exim.conf

它不会替换任何东西,也不显示任何错误消息

我一直在玩它,但是我尝试的所有方法都不起作用。


是否需要,sed或者您愿意使用其他工具?街"区内可以有text=吗?text = 文件中是否还有其他情况?总是会有4行文字,还是会有更多/更少?
terdon

最好是sed,或不需要在CentOS服务器中安装的任何内容。开箱即用的工具
blade19899

@terdon text = 文件夹中没有其他文件,需要输出text = ""。这些文件具有891行代码。因此,它需要尊重其他文本。
blade19899 '16

您要覆盖文件还是只修改输出?
joH1

@Moonstroke没有覆盖。正如我的问题所示,它只需要替换文本即可text = ""。正如我的问题所示。
blade19899 '16

Answers:


15

Perl解救:

perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
  • -i~ 将在“原地”编辑文件,保留备份副本
  • -0777 一次读取整个文件,而不是逐行读取

替换的s///工作方式与sed中的类似(即,它匹配text = "后跟多次,但双引号多次直到双引号),但是在这种情况下,它对整个文件有效。


5

您必须检查模式空间,并在N不匹配的情况下继续拉入分机线,例如

sed '/text = "/{              # if line matches text = "
:b                            # label b
$!N                           # pull in the next line (if not the last one)
/"$/!bb                       # if pattern space doesn't end with " go to label b
s/".*"/""/                    # else remove everything between the quotes
}' infile

gnu sed你可以写成

sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile

但这不是很有效,最好只是选择range /text = "/,/"/,修改第一行并删除其余的行:

sed '/text = "/,/"/{            # in this range
/text = "/!d                    # delete all lines not matching text = "
s/\\/"/                         # replace the backslash with quotes (this is only
}' infile                       # executed if the previous d wasn't executed)

再次,gnu sed您可以将其编写为单线:

sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile

3

就个人而言,我将在Perl中执行此操作。如果我们可以假设"在结束之前没有,则"可以执行以下操作:

perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file

-0吸食整个文件,将其读入内存中。该-p手段“将给出脚本后‘(将整个文件打印的每一行这里,一个’行)-e”。脚本本身是一个简单的替换运算符。它将捕获字符串,text后接0个或多个空格字符,=再次捕获一个和0个或多个空格字符(text\s*=\s*),并将其另存为$1。然后,它将用模式($1)和替换捕获的模式以及找到的最短引用的字符串""。该s标志使.匹配换行符。


更正,请-00阅读段落,而不是整个文件(ref)。如果引号中的文本包含空白行,则正则表达式将不匹配。
格琳·杰克曼

@glennjackman啊!我总是把那些混在一起。。这就是为什么我实际上通过添加额外的段落并运行来仔细检查的原因perl -00ne 'print;exit'。而且我仍然在回答中输入错误的答案!谢谢,现在修复。
terdon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.