입력 파일에서 데이터를 읽고 데이터를 xml의 적절한 필드에 넣습니다.

입력 파일에서 데이터를 읽고 데이터를 xml의 적절한 필드에 넣습니다.

입력 파일과 xml 파일이 있습니다.

입력 파일-

/user/sht
227_89,45_99
/user/sht1
230_90
/user/sht2
441_50

파일에는 경로와 위치를 포함하는 대체 줄이 있습니다.

xml 파일 -

<aaa><command name="move">
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
<domain>
<path></path>
<positions></positions>
</domain>
</command>
</aaa>

다음 필수 출력 xml을 제공하는 스크립트를 작성한 후 다음 xml을 입력으로 사용하여 일부 명령을 실행해야 합니다.

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

입력 파일에서 한 줄씩 추출하여 xml에 넣어 보았지만 문제는 모든 항목이 <path>첫 번째 입력 줄로 대체된다는 것입니다.

GNU bash 사용 4.1.2.

답변1

GNU sed스크립트를 사용하면 다음과 같은 작업을 수행할 수 있습니다.

sed -n '/<aaa>/,/<.aaa>/!{H;d}
G;:a
s_>\(</path>.*\n\)\n\([^\n]*\)_>\2\1_
s_>\(</positions>.*\n\)\n\([^\n]*\)_>\2\1_;
ta;P;s/.*\n\n/\n/;h' input.txt input.xml

첫 번째 라인은 보존 버퍼에 있는 첫 번째 파일의 모든 라인을 수집합니다.

그런 다음 두 번째 파일의 각 라인에 대해 보유 버퍼가 추가됩니다 G. 그렇다면 두 명령 중 하나를 path사용하여 레이블 내부에서 보유 버퍼의 첫 번째 세그먼트를 이동하십시오.positionss

어떤 경우든 해당 행은 인쇄 P되고( ) 삭제되며( s/.*\n\n/\n/) 교체 목록의 나머지 부분은 다음 주기( h)를 위해 저장 버퍼로 다시 이동됩니다.

답변2

쉘 스크립트가 귀하의 요구 사항을 충족합니다

#!/bin/bash
count=0          ## counting lines
while read var
do
    occurance=$[$count/2+1];                  ## check nth occurance of search path/position from file
if [ $((count%2)) -eq 0 ];                ## If counting even replace path values else replace position values
then
    perl -pe 's{<path>*}{++$n == '$occurance' ? "<path>'$var'" : $&}ge' xml > xml1
else
    perl -pe 's{<positions>*}{++$n == '$occurance' ? "<positions>'$var'" : $&}ge' xml > xml1
fi
yes|cp xml1 xml
    count=$[$count +1]
done <./input
rm xml1 

답변3

다음과 같이 GNU sed 및 XML 형식을 사용하십시오.

sed -e '
   /<domain>/,/<\/domain>/!b
   /<\(path\|positions\)><\/\1>/!b
   s//<\1>/
   R input_file
' XML_file |
sed -e '
   /<\(path\|positions\)>.*/N
   s//&\n<\/\1>/
   s/\n//g
'

결과

<aaa><command name="move">
<domain>
<path>/user/sht</path>
<positions>227_89,45_99</positions>
</domain>
<domain>
<path>/user/sht1</path>
<positions>230_90</positions>
</domain>
<domain>
<path>/user/sht2</path>
<positions>441_50</positions>
</domain>
</command>
</aaa>

답변4

셸에서:

echo '<aaa><command name="move">'
echo '<domain>'

while true
do read v || break
   echo "<path>$v</path>"
   read v || break
   echo "<positions>$v</positions>"
done < /path/to/YourInputFile

echo '</domain>
</command>
</aaa>'

관련 정보