特定のパターンの後に行セットを追加する必要があるファイルがあります。問題は、複数行のパターンを処理できないことです。
模様
<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のステートマシンメソッド各行を印刷します。必要な3行が連続して表示される場合、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
ディレクティブを使用して入力ストリーム(文字列の怠惰なリスト)から2つのポイントをキャプチャし、次にLisp関数を使用してその2つのポイント(つまり一致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)
と同じです。s/regexp/replace/
静的単語ではなくテキストを抽出し、現在表示されているすべての場所にそのテキストをコピーする必要があるとします。\1
\2
&
TestPlan
TestPlan
@(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
正常に動作し、コードを読み取ることができます。複数行のテキストがそのまま表示されます。その
@
キャラクターが出てきたら2倍に増やさなければなりませんが、そうでは@@
ありません。