파일에서 문자열을 검색한 다음 이를 변수로 사용하는 방법은 무엇입니까?

파일에서 문자열을 검색한 다음 이를 변수로 사용하는 방법은 무엇입니까?

다음과 같은 XML 파일이 있습니다.

<id>456</id>

<root>
<value>1</value>
<intNum>2</intNum>
</root>

<root>
<eulav>1</eulav>
<muNtni>2</muNtni>
</root>   

<id>456</id>나는 기억 하고 다음을 수행하고 싶습니다 .

sed 's/\<root\>/\
\<root\> 
$herecomestheid

기본적으로 이것이 하는 일은 <root>로 바꾸는 것입니다 <root>\n<id>456</id>. \n이 경우 개행을 의미합니다. 나는 이것을 이미 알고 있지만, 내가 겪고 있는 문제는 그것을 기억 <id>456</id>하고 나중에 사용하기 위해 보관하는 것입니다.

나는 이것을 시도했습니다 (분명히 작동하지 않습니다).

 sed -i '' 's/\<root\>/\
 \<root\>\
 \<id\>.\<\/id\>/g'

나는 다음과 같이하려고합니다 :

cat file.xml | grep '\<id\>*\<\/id\>'

grep 출력을 변수에 넣어보십시오. 이것도 분명히 작동하지 않습니다.

편집: <id>*</id>루트 디렉터리에 있어야 합니다.

답변1

XML을 텍스트로 처리하는 것은 일반적으로 신뢰할 수 있는 솔루션이 아니지만 그렇게 해야 한다고 주장한다면 sed를 사용할 수 있습니다.예비 공간 예를 들어

sed -e '/<id>[0-9]*<\/id>/h' -e '/<root>/{x;p;x;}' file.xml

답변2

sed -e :b -e '$!{N;\|<id>.*\n<root>|!bb
};do what ever you want to do with all of those lines now....'

나는 oldspace가 아마도 최선의 선택일 것이라는 Steeldriver의 의견에 동의 h하지만 다른 옵션도 있습니다. 때때로 우리는 두 개의 버퍼를 관리하기에는 너무 게으른 경우가 있습니다. 또는 이것이 일반적으로 내 문제입니다.두 개의 버퍼를 관리합니다. 위의 코드 조각은 패턴 공간에 줄을 쌓습니다. 을 텐데항상 태그 사이에 나타나며 <id>, 라인 2로 이동하기 전에 항상 필요한 데이터 청크로 패턴 공간을 재귀적으로 채웁니다.즉, 버퍼가 동시에 붕괴되지 않는 한 그렇게 할 것입니다. 하지만 이제는 그렇게 하기가 다소 어렵습니다..

h또한, 예전의 우주 문제 로 돌아가서 , 전자적 x변화는교환 h오래되고 패턴화된 공간. 한 번 사용하면 모드 버퍼가 h이전 버퍼로 렌더링되고 그 반대의 경우도 마찬가지입니다. 이 효과는 라인 사이클 동안 지속됩니다. 내가 일반적으로 하는 일은 시작선에 도달할 때까지 파일을 읽고, 예비 편집을 수행한 다음, H다른 상태를 얻을 때까지 이전 상태를 교환하고 유지하는 것입니다. 내 스크립트가 다시 바뀌면 한 블록 뒤쳐집니다. 마지막으로 열었던 태그 H와 동시에 모든 필드가 뒤쳐집니다. 필요할 때 필요한 만큼만 버퍼링하는 간단한 방법입니다.

원하는 루프를 달성하는 또 다른 방법은 다음과 같습니다.

sed -e '/<id>/h;//!H;/<root>/!{$!d' -e '};x...'

그 시점부터 패턴 공간은 H이전 공간이 되고 그 반대도 마찬가지입니다. h옛 의지씌우다 h이전 공간이 사용될 때마다 현재 모드 공간과 함께 사용됩니다. 따라서 위의 예에서는 <id>매번 한 줄로 새 버퍼를 시작합니다.!H 추가H이전 공간의 모든 중간 줄 뒤에는 \n줄 문자가 옵니다. 현재 라인이 안전하게 들어가고 다음 라인 루프가 시작되면 $!d마지막 라인이 아닌 모든 라인의 패턴 공간이 제거되므로 일치를 기다리는 전체 블록에서만 변경이 발생합니다.!$Hx<root>

당신의 그것을 기억하십시오마침내<root>차단하면 일치 항목과 다를 경우 태그가 마지막 줄이 될 수 있습니다 .

하지만...

편집 내용에 따르면 탈출할 수 없는 이유가 없다고 생각됩니다.

sed '/<id>/h;//d;\|</root>|G
' <<\INPUT
unimportant 1
<id> number 1 </id>
<root> sub text
more text
 more text
</root>
<root> sub text as well
and more text
and more text
</root>
unimportant 2
<id> number 2 </id>
<root> sub text
more text
more text
</root>
<root> sub text
and more text
and more text
</root>
INPUT

필드 <id>인 줄이 있습니다 .h(다시 말하지만 h이전 공간 덮어쓰기)그런 다음 d출력에서 ​​제거하십시오. 일치가 발생 하면 다음과 같이 </root>라인 사이클의 끝에서 결과를 자동으로 인쇄하기 전에 이전 공간이 패턴 공간에 추가됩니다 .sed Gh

unimportant 1
<root> sub text 
more text
 more text
</root>
<id> number 1 </id>
<root> sub text as well
and more text
and more text
</root>
<id> number 1 </id>
unimportant 2
<root> sub text
more text
more text
</root>
<id> number 2 </id>
<root> sub text
and more text
and more text
</root>
<id> number 2 </id>

답변3

사용된 솔루션 awk

awk '/<id>/{id=$0}/<root>/{print id}1' file.xml

해당 줄을 인쇄하지 않으려면 를 <id>추가하여 건너뛸 수 있습니다 next.

awk '/<id>/{id=$0;next}/<root>/{print id}1' file.xml

관련 정보