쉘 스크립트의 태그에서 한 줄을 제거하는 방법은 무엇입니까?

쉘 스크립트의 태그에서 한 줄을 제거하는 방법은 무엇입니까?

(abc_lop.xml)태그에 존재하는 줄을 삭제해야 하는 XML 파일이 있습니다 .

아래는 xml 파일이 꽤 크기 때문에 줄여서 만든 것입니다.

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">


    <!-- some data here  -->

</HELLO>

보시다시피 위의 태그 xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd"에 다음 줄이 있습니다 . HELLO이 줄을 제거하고 다른 줄을 유지해야 합니다.

현재로서는 쉘 스크립트에 아래와 같이 위의 xml 파일에 머리글과 바닥글을 추가한 다음 파일 변수에 저장하고 $word있습니다 abc.

file=$(printf '%s\n%s\n%s' "$header" "$(cat "$path/${word}_lop.xml")" "$footer")

HELLO이제 파일 변수에 xml 파일 데이터가 있어야 하지만 태그에서 해당 줄 도 제거해야 하는지 확인하고 싶습니다 .

이 변수는 나중에 다른 용도로 사용할 예정이므로 머리글, 바닥글, 행도 함께 제거해야 하는지 $file확인하고 싶습니다 . $file키=값 쌍이 있는 행은 한 번만 나타납니다.

답변1

XML을 수정하기 위해 정규식을 사용하지 마십시오. XML 사양에서는 정규식 기반 구문 분석에서 제대로 작동하지 않는 몇 가지 사항을 허용합니다.

깨지기 쉬운 코드를 생성하기 때문에 이는 매우 나쁜 생각입니다. 어느 날, 사용 중인 소스 XML이 (XML 사양에 관한 한) 완전히 유효한 다른 것으로 변경될 수 있으며 다운스트림 수정 스크립트가 중단될 수 있습니다.

이것이 바로 시스템 관리자와 유지보수 프로그래머를 매우 슬프게 만드는 종류의 일입니다.

XML 파서를 사용하세요. xmlstarlet선택이다. 둘 다 구문 분석 옵션도 있습니다 perl. python이 두 가지 모두 XML의 이상한 상황(예: 줄 바꿈, 예쁜 인쇄 등)을 처리하고 다운스트림 XML이 유효한지 확인합니다. XML이 유효하지 않기 때문에 유효한 XML을 출력하는 것이 중요합니다.~해야 한다치명적인 상태가 됩니다.

구체적으로 - HELLO요소에서 속성을 제거합니다.

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a' ) -> parse ( \*DATA );

foreach my $hello ( $twig -> findnodes ('//HELLO') ) {
    $hello -> del_att('xmlns:xsi');
}
$twig -> print;

__DATA__
<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">


    <!-- some data here  -->

</HELLO>

참고 - 결과를 "예쁘게 인쇄"했습니다.

<HELLO
    version="4.2"
    xmlns="http://www.bacd.org/HELLO-4_2"
    xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">
    <!-- some data here  -->
</HELLO>

정규식 기반 구문 분석이 왜 나쁜 생각인지 예를 들어주세요. 왜냐하면 그것이 유효한 XML이기 때문입니다.

또한 이렇습니다:

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd">
    <!-- some data here  -->
</HELLO>

그리고:

<HELLO
version="4.2"
xmlns="http://www.bacd.org/HELLO-4_2"
xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd"
>
    <!-- some data here  -->
</HELLO>

그리고:

<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xsi:schemaLocation="http://www.bacd.org/HELLO-4_2 http://www.bacd.org/v4-2/hello-4-2.xsd"><!-- some data here  --></HELLO>

그러나 XML 파서는 간단하고 사용하기 쉽습니다.

코드를 sed와 같은 한 줄의 코드로 줄이려면 다음을 수행하세요.

perl -0777 -MXML::Twig -e 'XML::Twig -> new ( pretty_print => "indented_a", twig_handlers => { "HELLO" => sub { $_ -> del_att("xmlns:xsi") }} ) -> parse ( <> ) -> print;'

STDIN을 통해 또는 파일 이름을 지정하여 데이터를 제공하는 경우 작동합니다.

답변2

이 항목을 제거 xsi:schemaLocation하고 파일의 나머지 부분을 변경하지 않고 그대로 두려면 다음을 수행하십시오.

$ sed 's/xsi:schemaLocation="[^"]*"//' "$path/${word}_lop.xml"
<HELLO version="4.2" xmlns="http://www.bacd.org/HELLO-4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >


    <!-- some data here  -->

</HELLO>

s/xsi:schemaLocation="[^"]*"//대체 명령입니다. xsi:schemaLocation="[^"]*"정규식과 일치하는 모든 항목을 아무것도 대체하지 않습니다 .

이것을 스크립트와 결합하려면 다음을 수행하십시오.

file=$(printf '%s\n%s\n%s' "$header" "$(sed 's/xsi:schemaLocation="[^"]*"//' "$path/${word}_lop.xml")" "$footer")

관련 정보