sed: 첫 번째 와일드카드 문자만 교체

sed: 첫 번째 와일드카드 문자만 교체

저는 XML 파일의 속성을 대체하기 위해 sed를 사용하고 있는데 지금까지는 훌륭하게 작동하고 있습니다.

다음과 같은 태그가 포함된 XML 파일이 있습니다.

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160406155451.eba"
    name="com.mycompany.site.app" />

새 EBA 파일이 배포될 때마다 위치 속성을 바꿔야 합니다. 예: (다른 빌드 타임스탬프)

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160410173452.eba"
    name="com.mycompany.site.app" />

sed라벨이 있는 표현식을 사용하여 이 작업을 수행합니다 .

:a;N;$!ba;0,s|<osgiApplication id="com.mycompany.site.app".*\/>|<osgiApplication id="com.mycompany.site.app" location="com.mycompany.site.app-1.0.0.20160406155451.eba"

작동 중이야완벽한, 실제로 다른 태그가 있는 또 다른 상황이 발생할 때까지 <osgiApplication>. 예를 들어:

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160406155451.eba"
    name="com.mycompany.site.app" />

<anotherTag />

이런 일이 발생하면 .*\/>sed 표현식의 기준 으로 인해모든 것끝까지 교체하지 않았습니다 />. 첫 번째 항목만 바꾸고 싶습니다.

즉, 다음과 같은 경우가 있습니다.

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160406155451.eba"
    name="com.mycompany.site.app" />
<anotherTag />
<anotherTag />
<anotherTag />

내가 원하는 대체품은 다음과 같습니다.

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160410173452.eba"
    name="com.mycompany.site.app" />
<anotherTag />
<anotherTag />
<anotherTag />

하지만 내가 현재 얻는 것은 다음과 같습니다.

<osgiApplication id="com.mycompany.site.app"
    location="com.mycompany.site.app-1.0.0.20160410173452.eba"
    name="com.mycompany.site.app" />

해결책을 찾고 있었지만 찾지 못했습니다. 어떤 제안이라도 주시면 감사하겠습니다. 감사합니다.

답변1

귀하의 질문에 대한 가장 좋은 답변은 실제로 정식입니다.sed를 사용하지 마세요. 문제가 라인 지향적이고 RE로 표현될 수 없다면 sed는 잘못된 도구입니다. 상황은 다음과 같습니다. XML은 일반 언어가 아니기 때문에어느복잡성이 충분히 주어지면 RE는 조만간 실패할 것입니다. 신뢰할 수 있는 유일한 솔루션은 Python 표준 라이브러리의 SAX 파서와 같은 XML 파서를 사용하는 것입니다.

그럼에도 불구하고 한 명의 훌륭한 해커는 다른 해커를 만날 자격이 있습니다. SAX 파서에서 작업하는 동안 스크립트가 다시 작동하도록 하려면 더 제한적인 RE 또는 awk라는 두 가지 방법을 시도해 볼 수 있습니다.

([^/>]+)대신 더 엄격한 RE를 사용할 수 있습니다 .*. RE로 끝나는 파일 이름으로 인해 화상을 입을 수도 있지만 >이를 방지할 수 있습니다. 어쨌든 제작자는 그러한 파일 이름을 만들지 않을 것입니다. 전문가 팁: 가 포함된 울타리 기둥을 찾을 때는 .*부정적인 문자 클래스를 사용하세요.

더 나은 옵션은 awk입니다.

# use awk -F '["]' to set FS to a double-quote character
/<osgiApplication id=.*app"/ {
    APP=$2
    next
}
APP && /location=/ {
    if (index($2, APP) {
        substr($2, REPLACEMENT, $0)
    }
    APP = ""
}

이는 적절한 시작 태그가 발견되면 이를 사용자가 제공한 REPLACMENT 명명된 문자열로 대체하여 APP를 설정합니다. /[/]> *$/설정 중 이러한 상황이 발생 하면 더욱 주의하시기 바랍니다. 앱을 재설정하고 경고를 보내주세요. 하지만 줄의 시작/끝에서 태그가 시작하고 멈추는 위치를 알려주는 XML에는 아무것도 없기 때문에 우리는 여전히 해킹을 하고 있습니다.

관련 정보