S
문자를 다음으로 바꿔야 합니다 T
.
<episode-num system="onscreen">S1 E12</episode-num>
내 예상 결과:
<episode-num system="onscreen">T1 E12</episode-num>
Git이 어떻게 깊이 있게 작동하는지 모르겠지만, 그냥 XML 태그의 해당 문자를 바꾸는 데 사용했고, 포럼에서 조사한 결과 몇 가지 정보를 발견하고 다음 명령줄을 시도했습니다.
sed -e :l -e 's@\(<episode-num system="onscreen">.*\)S\([^amp;]\)\(.*</episode-num>\)@\1T\2\3@;tl' guide.xml
하지만 작동하지 않습니다. 도와주세요.
답변1
다음과 같은 XML 문서가 있다고 가정해 보겠습니다.
<data>
<episode-num system="onscreen">S1 E12</episode-num>
<episode-num system="onscreen">S1 S12</episode-num>
<episode-num system="onscreen">T1 S12</episode-num>
</data>
S
...노드 값의 모든 문자를 바꾸려고 합니다.T
episode-num
에서 시작하다S
.
xmlstarlet
다음을 수행할 수 있습니다.
xmlstarlet ed -u '//episode-num[starts-with(text(),"S")]' \
-x 'translate(text(),"S","T")' file.xml
episode-num
문서 내 위치에 관계없이 모든 노드를 수정할 수 있습니다 . 그냥 수정하고 싶다면특별한노드를 클릭하고 //episode-num
XPath 표현식을 더 정확한 경로로 변경하세요.
위의 예제 문서에서 xmlstarlet
위 명령은 다음을 생성합니다.
<?xml version="1.0"?>
<data>
<episode-num system="onscreen">T1 E12</episode-num>
<episode-num system="onscreen">T1 T12</episode-num>
<episode-num system="onscreen">T1 S12</episode-num>
</data>
와 xq
(부터https://kislyuk.github.io/yq/) 같은 xmlstarlet
상기와:
xq -x '(.data."episode-num"[] | select (."#text"|startswith("S")))."#text" |= gsub("S";"T")' file.xml
이는 입력 문서가 예제 문서와 동일한 구조를 가지고 있다고 가정합니다. XML 파서를 사용하여 문서를 구문 분석하고 내부적으로 JSON으로 변환합니다. 생성된 JSON 문서를 호출하여 jq
주어진 표현식을 적용하고 마지막으로 모든 것을 다시 XML로 변환합니다.
내가 사용하고 있는 예제 문서의 경우 표현식이 실제로 적용되는 내부 JSON 문서는 jq
다음과 같습니다.
{
"data": {
"episode-num": [
{
"@system": "onscreen",
"#text": "S1 E12"
},
{
"@system": "onscreen",
"#text": "S1 S12"
},
{
"@system": "onscreen",
"#text": "T1 S12"
}
]
}
}
답변2
줄에 다른 문자열이 포함된 경우에만 특정 문자열을 바꿉니다.sed
문자열을 포함하는 줄만 바꿉니다.free
sed '/free/s/i/I/g' example.txt
'/free/s/i/I/g'
/free/
- 이 문자열이 포함된 경우에만 줄을 바꿉니다.s
- sed에 대한 대체 명령/i/
- 일치시키려는 정규식은 무엇입니까?/I/
- 일치하는 하위 문자열 바꾸기/g
- 라인의 모든 경기에 대해 교체를 반복하는 교체 플래그
가설에 대한 해결책
귀하의 테스트 문자열은<episode-num system="onscreen">
다음 내용이 포함된 파일이 있다고 가정해 보겠습니다.
$ cat test.xml
<data>
<episode-num system="onscreen">S1 E11</episode-num>
<episode-num system="onscreen">S1 E12</episode-num>
<episode-num system="onscreen">T1 E13</episode-num>
<some data>S1 E1</episode-num>
</data>
귀하의 sed 솔루션은 다음과 같습니다
$ sed '/<episode-num system="onscreen">/s/S/T/g' test.xml
<data>
<episode-num system="onscreen">T1 E11</episode-num>
<episode-num system="onscreen">T1 E12</episode-num>
<episode-num system="onscreen">T1 E13</episode-num>
<some data>S1 E1</episode-num>
</data>
이 솔루션의 출처는여기.
답변3
Perl one-ligner는 좋은 접근 방식이 아닙니다. 그래도:
perl -MXML::DT -e 'print dt("ex1.xml", "episode-num" => sub{$c=~ s/S/T/; toxml})'
어디:
-XML::DT
= XML::DT 모듈을 가져와 사용합니다(이 경우dt
함수dt( file, processor)
= 제공된 프로세서를 사용하여 파일을 아래로 번역episode-num => sub{...}
=sub
모든 요소에 적용episode-sum
$c = s/S/T/ ; toxml
= 요소 콘텐츠에서 S를 T(=$c)로 바꾸고episode
XML 요소를 다시 계산합니다.
(필요하다면 sudo cpanm XML::DT
)