특정 패턴 뒤에 줄 집합을 추가해야 하는 파일이 있습니다. 문제는 여러 줄의 패턴을 처리할 수 없다는 것입니다.
무늬
<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
0으로 재설정됩니다.
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)
과 같습니다. 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배로 늘려야 하는데 @@
그렇지 않더군요.