다음 유형의 줄이 포함된 큰 xml 파일이 있습니다.
<test type="one" valid="yes" description="something">
twilight-.*\.iso\.auth</test>
<test type="one" valid="no" description="something else">
testlite-.*\.cop</test>
<test type="two" valid="yes" description="something else">
messing-.*\.cop\.auth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.auth</test>
내 XML 파일에는 이와 같은 줄이 많이 있습니다. 내 요구 사항은 다음과 같습니다
- 첫 번째 줄의 "valid="yes"" 패턴과 두 번째 줄의 ".auth" 패턴이 일치하면 이 두 줄이 복사됩니다. 두 번째 줄에서 ".auth"를 ".newauth"로 바꿉니다.
- 같은 줄에서 "valid="yes"와 ".auth" 패턴이 일치하면 해당 줄을 복사하고 ".auth"를 ".newauth"로 바꾸세요.
출력은 다음과 같아야 합니다.
<test type="one" valid="yes" description="something">
twilight-.*\.iso\.auth</test>
<test type="one" valid="yes" description="something">
twilight-.*\.iso\.newauth</test>
<test type="one" valid="no" description="something else">
testlite-.*\.cop</test>
<test type="two" valid="yes" description="something else">
messing-.*\.cop\.auth</test>
<test type="two" valid="yes" description="something else">
messing-.*\.cop\.newauth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.auth</test>
<test type="three" valid="yes" description="something else">messing-.*\.cop\.newauth</test>
내 xml 파일에는 교체해야 할 여러 줄(쌍)이 있다는 점에 유의하세요. 그러나 교체 규칙은 위와 동일합니다. 또한 네 번째 줄의 경우 전체 xml 태그가 한 줄의 일부라는 점에 유의하세요. 따라서 이 경우 awk 표현식은 약간 더 복잡해집니다.
미리 감사드립니다!
답변1
수정된 질문에 맞춰 업데이트됨
이 시도. GNU awk 4.2.1에서는 잘 작동하는 것 같습니다.
awk '/valid="yes"/{print;if(!/<\/test>/){a=$0;getline;print $0"\n"a}gsub(/\.auth/,".newauth")}1' filename
답변2
다음과 같이 편집기를 사용하여 sed
이 작업을 쉽게 수행할 수 있습니다 .
$ sed -e '
/valid="yes"/!b
h;/\.auth/G
/\n/P;//s/.*\n//
s/\.auth/.newauth/;t
$q;N;/\.auth/!{P;D;}
p;s//.newauth/
' test.xml
답변3
@Steve의 솔루션을 기반으로 한 2단계 프로세스를 통해 원하는 것을 달성할 수 있었습니다.
- 해결책 #1:
awk '/valid="yes"/{print;a=$0; next} /.auth/{print $0"\n"a;gsub(/\.auth/,".newauth")}1' test.xml > newtest.xml
- 위 단계의 xml 파일을 사용하여 #2를 해결하세요.
awk '/valid="yes"/ && /.auth/{print $0;gsub(/\.auth/,".newauth")}1' newtest.xml > final.xml
이 두 작업을 하나의 awk 작업으로 결합할 수 있습니까?
답변4
자신이 수행 중인 작업을 실제로 알고 있고 XML이 다른 형식일 수 없거나 문제를 포함할 수 없다면 두 단계나 복잡한 스크립트가 필요하지 않습니다. 이 작업은 한 번만 수행하면 됩니다.
sed -e '/valid="yes"/!b' -e '/\.auth/!N;p;s/\.auth/.newauth/'
/valid="yes"/!b
패턴( )이 포함되지 않은 줄의 경우b
스크립트 끝으로 이동하므로!
다른 모든 내용은 그대로 유지됩니다./\.auth/!N
!
( )를 포함하지 않는 줄 에 적용됩니다 . 이 줄에는 ext 줄을.auth
추가합니다.N
p
현재 패턴 공간을 인쇄합니다(한 줄 또는 두 줄일 수 있음). 어쨌든 필요에 따라 카피한다s/\.auth/.newauth/
필요한 교체를 수행합니다. 수정되지 않은 라인이 인쇄되었습니다p
. 이제 이를 반복하도록 수정하고 일반 처리가 끝나면 인쇄됩니다.- 5단계? 5단계는 없습니다.