Unix sed 출력이 대체 패턴으로 두 번 나타납니다.

Unix sed 출력이 대체 패턴으로 두 번 나타납니다.

XML 파일이 있습니다 logback-spring.xml.

이제 문자열 이 나타날 때마다 DEBUG로 바꾸고 싶습니다 .TRACEref="logstash"다음 줄에만.

입력 파일은 다음과 같습니다.

  <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
        <appender-ref ref="logstash"/>
        <appender-ref ref="Async-Appender"/>
    </logger>

  <springProfile name="dev">
        <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
            <appender-ref ref="logstash"/>
        </logger>
  <springProfile name="dev">
        <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE"/>
        </logger>

명령을 사용할 때 sed출력을 얻습니다.두 배교체 중입니다.

다음 sed명령을 사용했습니다.

sed -n -e '/ref="logstash"/!h' -e '/ref="logstash"/{H;x;s/DEBUG/TRACE/}; p; ' logback-spring.xml

답변1

다음과 같은 올바른 형식의 XML 문서가 제공됩니다(예제에 맞게 수정됨).

<?xml version="1.0"?>
<root>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
      <appender-ref ref="logstash"/>
      <appender-ref ref="Async-Appender"/>
    </logger>
  </springProfile>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
      <appender-ref ref="logstash"/>
    </logger>
  </springProfile>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
      <appender-ref ref="CONSOLE"/>
    </logger>
  </springProfile>
</root>

xmlstarlet다음과 같이 하위 노드의 속성이 using level으로 설정된 각 노드의 모든 속성을 변경할 수 있습니다 DEBUG.TRACEloggerappender-refreflogstash

$ xmlstarlet ed -u '//logger[appender-ref/@ref = "logstash"]/@level[. = "DEBUG"]' -v 'TRACE' file.xml
<?xml version="1.0"?>
<root>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="TRACE" additivity="false">
      <appender-ref ref="logstash"/>
      <appender-ref ref="Async-Appender"/>
    </logger>
  </springProfile>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="TRACE" additivity="false">
      <appender-ref ref="logstash"/>
    </logger>
  </springProfile>
  <springProfile name="dev">
    <logger name="com.abcd.tdi" level="DEBUG" additivity="false">
      <appender-ref ref="CONSOLE"/>
    </logger>
  </springProfile>
</root>

XPath 쿼리는 다음과 같습니다.초로바는 뭐 쓰는거야?또한 작동합니다:

xmlstarlet ed -u '//logger[@level = "DEBUG"][appender-ref/@ref = "logstash"]/@level' -v 'TRACE' file.xml

답변2

XML로 작업할 때는 XML 인식 도구를 사용하십시오. 예를 들어,xsh, 래퍼XML::LibXML, 다음을 통해 결과를 얻을 수 있습니다.

open logback-spring.xml ;
for //logger[@level='DEBUG'][appender-ref/@ref='logstash']
    set @level 'TRACE' ;
save :b ;

XML에 네임스페이스 선언이 포함되어 있으면 코드가 약간 더 복잡해집니다.

관련 정보