如何在文件中的多行模式之后添加多行?

如何在文件中的多行模式之后添加多行?

我有一个文件,需要在某种模式后添加一组行。问题是我无法处理有多行的模式。

图案

<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>

要在此模式后添加的行

<org.apache.jmeter.config.RestServerNodeElement guiclass="TestBeanGUI"
  testclass="org.apache.jmeter.config.RestServerNodeElement"
  testname="ATC_Test_Lab" enabled="true">
<stringProp name="TestPlan.comments"> </stringProp>
<stringProp name="authbasic">${Basic}</stringProp>
<stringProp name="authpassword">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>
<stringProp name="authuser">${User}</stringProp>
<stringProp name="extratag"></stringProp>

我尝试了sed带有以下选项的命令-r,但它不起作用

sed -i.bak '/^<stringProp
name="TestPlan.user_define_classpath"></stringProp>/{N;/\n</TestPlan>/{N;/\n<hashTree>/r
Config.jmx' $file

文件Config.jmx具有需要在此模式之后添加的行集。

错误:-

sed: -e expression #1, char 116: unterminated `s' command

答案1

让我们避免一些无聊的方法,比如用某种脚本语言将整行读取为字符串,并使用嵌入的换行符进行正则表达式替换。

Awk 中的状态机方法。打印每一行。如果所需的三行连续出现,则state变量递增到 2,并打印所需的块。对于任何其他输入,state将归零。

1
1 { print state }
state == 0 && /^<stringProp name="TestPlan.user_define_classpath"><\/stringProp>$/ {
  state++; next
}
state == 1 && /^<\/TestPlan>$/ {
  state++; next
}
state == 2 && /^<hashTree>$/ {
  print \
  "<org.apache.jmeter.config.RestServerNodeElement guiclass=\"TestBeanGUI\"\n" \
  "testclass=\"org.apache.jmeter.config.RestServerNodeElement\"\n" \
  "testname=\"ATC_Test_Lab\" enabled=\"true\">\n" \
  "<stringProp name=\"TestPlan.comments\"> </stringProp>\n" \
  "<stringProp name=\"authbasic\">${Basic}</stringProp>\n" \
  "<stringProp name=\"authpassword\">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>\n" \
  "<stringProp name=\"authuser\">${User}</stringProp>\n" \
  "<stringProp name=\"extratag\"></stringProp>\n"
}
1 {
  state = 0;
}

多行匹配并输出TXR。这里很少见的方法是使用data指令捕获输入流中的两个点(这是一个惰性字符串列表),然后使用 Lisp 函数ldiff获取这两个点之间的行范围(即匹配的块),以便它可以通过以下方式输出tprint

@(repeat)
@  (cases)
@    (data start)
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
@    (data end)
@    (do (tprint (ldiff start end)))
@    (output)
<org.apache.jmeter.config.RestServerNodeElement guiclass="TestBeanGUI"
  testclass="org.apache.jmeter.config.RestServerNodeElement"
  testname="ATC_Test_Lab" enabled="true">
<stringProp name="TestPlan.comments"> </stringProp>
<stringProp name="authbasic">${Basic}</stringProp>
<stringProp name="authpassword">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>
<stringProp name="authuser">${User}</stringProp>
<stringProp name="extratag"></stringProp>
@    (end)
@  (or)
@line
@    (do (put-line line))
@  (end)
@(end)

在这种方法中,我们可以将一些变量添加到正在匹配的代码块中,然后在@(output).有点像 a可以通过、等s/regexp/replace/引用捕获的片段。假设必须提取一段文本,而不是静态单词 ,并在现在出现的所有位置复制该文本:\1\2&TestPlanTestPlan

@(repeat)
@  (cases)
@    (data start)
<stringProp name="@TYPE.user_define_classpath"></stringProp>
</@TYPE>
<hashTree>
@    (data end)
@    (do (tprint (ldiff start end)))
@    (output)
<org.apache.jmeter.config.RestServerNodeElement guiclass="TestBeanGUI"
  testclass="org.apache.jmeter.config.RestServerNodeElement"
  testname="ATC_Test_Lab" enabled="true">
<stringProp name="@TYPE.comments"> </stringProp>
<stringProp name="authbasic">${Basic}</stringProp>
<stringProp name="authpassword">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>
<stringProp name="authuser">${User}</stringProp>
<stringProp name="extratag"></stringProp>
@    (end)
@  (or)
@line
@    (do (put-line line))
@  (end)
@(end)

让我们试试这个版本:

$ txr add.txr -
foo
foo
bar 
bar
blah
blah
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<org.apache.jmeter.config.RestServerNodeElement guiclass="TestBeanGUI"
  testclass="org.apache.jmeter.config.RestServerNodeElement"
  testname="ATC_Test_Lab" enabled="true">
<stringProp name="TestPlan.comments"> </stringProp>
<stringProp name="authbasic">${Basic}</stringProp>
<stringProp name="authpassword">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>
<stringProp name="authuser">${User}</stringProp>
<stringProp name="extratag"></stringProp>


blah
blah
blah
blah
<stringProp name="EvilPlan.user_define_classpath"></stringProp>  
</EvilPlan>
<hashTree>
<stringProp name="EvilPlan.user_define_classpath"></stringProp>
</EvilPlan>
<hashTree>
<org.apache.jmeter.config.RestServerNodeElement guiclass="TestBeanGUI"
  testclass="org.apache.jmeter.config.RestServerNodeElement"
  testname="ATC_Test_Lab" enabled="true">
<stringProp name="EvilPlan.comments"> </stringProp>
<stringProp name="authbasic">${Basic}</stringProp>
<stringProp name="authpassword">ENC(dsxxxxxxxxxxxWiu+FCzl5+A==)</stringProp>
<stringProp name="authuser">${User}</stringProp>
<stringProp name="extratag"></stringProp>
x
x
y
y
z
z

TestPlan更改为时EvilPlan,它工作得很好,并且代码可读:多行文本按原样表示。如果该 @字符出现,则必须将其加倍为@@,但它没有出现。

相关内容