작은 크기의 XML 파일이 있습니다. 이미 정보가 있으므로 XML 태그 사이에서 일부 값을 추출하기만 하면 됩니다. XML
내 컴퓨터에는 파서 유틸리티가 없기 때문입니다 . 나는 대안을 찾고 있습니다.
<capacity> </capacity
첫째, 중복된 XML 태그가 있습니다 . >NXML 파일의 시간 번호와 이 XML 태그 사이에는 다른 많은 태그가 있습니다.
<capacity> </capacity>
XML 태그의 각 항목을 개별적으로 가져온 다음 이를 구문 분석하고 그 아래의 값을 추출해야 합니다 .
<subcolumns><capacity><name>45.90</name>
<index>0</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
<capacity><name>57.09</name>
<index>1</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
<capacity><name>55</name>
<index>2</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
</subcolumns>
그래서 제가 생각하는 논리는 XML 태그의 첫 번째 항목을 찾아서 <capacity> </capacity>
임시 파일에 인쇄한 다음 첫 번째 항목을 삭제하는 것입니다.
<capacity><name>45.90</name>
<index>0</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
그런 다음 작업이 두 번째로 수행되면 <capacity> </capacity>
새 XML 태그 쌍이 고려됩니다. 따라서 <capacity> </capacity>
마지막 태그를 찾을 때까지 이 작업을 여러 번 반복해야 합니다 . 이 부분의 데이터는 추출될 때마다 변경되며 추출이 가능합니다.
<capacity> </capacity>
이제 내가 원하는 것은 기본 XML 파일에서 XML 태그의 첫 번째 항목을 선택하여 임시 파일로 인쇄하고 해당 부분을 삭제하는 것입니다.
이것이 내가 시도한 것이지만 아무것도 작동하지 않습니다.
sed -n '2,${/<capacity>\(.*\)<\/capacity>/\1/p;q;}' "<input XML file>" >> temp.txt
내 추가 아이디어는 임시 파일을 가져와서 태그 아래에 필요한 값을 처리하고 추출하는 것입니다 capacity
. 나는 이것에 대한 논리를 작성했고 잘 작동합니다.
답변1
XML 파서를 사용하는 것은 XML 문서를 조작하는 올바른 방법입니다.
xmlstarlet해결책:
xmlstarlet sel -t -c '//capacity[1]' -n yourxml > temp.txt
&& xmlstarlet ed -d '//capacity[1]' yourxml > tmp.xml && mv tmp.xml yourxml
cat temp.txt
<capacity><name>45.90</name>
<index>0</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
xmlstarlet sel -t -c '//capacity[1]' -n yourxml > temp.txt
- 첫 번째capacity
태그 선언을 추출하고 출력을 다음으로 리디렉션합니다.temp.txt
xmlstarlet ed -d '//capacity[1]' yourxml > tmp.xml
capacity
-문서에서 첫 번째 태그를 제거하고(-d
삭제 작업을 통해) 수정된 문서 내용을 임시 파일로 리디렉션합니다.tmp.xml
mv tmp.xml yourxml
- 초기 XML 문서를 수정된 버전으로 교체
답변2
XML 파서가 없으므로 gnu awk로 이것을 시도해 보십시오:
$ awk -v RS="<subcolumns>|</capacity>" 'NR==2{gsub(/^\n/,"");print $0 RT;exit}' file.xml
<capacity><name>45.90</name>
<index>0</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
이것이 작동하는 이유:
awk에서는 사용자 정의 레코드/줄 구분 기호를 설정할 수 있습니다. 이 예에서는 <subcolumns>
또는</capacity>
따라서 레코드 구분 기호를 사용자 정의하면 다음 형식을 얻을 수 있습니다.
$ awk -v RS="<subcolumns>|</capacity>" '{gsub(/^\n/,"");print NR,$0 RT}' file.xml
1 <subcolumns>
2 <capacity><name>45.90</name>
<index>0</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
3 <capacity><name>57.09</name>
<index>1</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
4 <capacity><name>55</name>
<index>2</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
5 </subcolumns>
추신: NR = 숫자 또는 레코드/행. RT=사용할 레코드 구분 기호입니다.
따라서 <capacity></capacity>
NR 번호를 조정하여 모든 블록을 인쇄할 수 있습니다.
$ awk -v RS="<subcolumns>|</capacity>" 'NR==4{gsub(/^\n/,"");print $0 RT}'
<capacity><name>55</name>
<index>2</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
따라서 섹션(예: 첫 번째 용량 섹션)을 건너뛰어야 하는 경우 <capacity>
다음을 수행할 수 있습니다.
$ awk -v RS="<subcolumns>|</capacity>" '{gsub(/^\n/,"")}NR!=2{print $0 RT}'
<subcolumns>
<capacity><name>57.09</name>
<index>1</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
<capacity><name>55</name>
<index>2</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>
</subcolumns>
답변3
chunk=2; # specify the tag chunk number here which must be > 0
perl -l -0777ne "print((m{(<capacity>.*?</capacity>)}sg)[${chunk:-1}-1])" yourxmlfile
결과
<capacity><name>57.09</name>
<index>1</index>
<value_type>String</value_type>
<ignore_case_flag>1</ignore_case_flag>
<hidden_flag>0</hidden_flag>
<exclude_from_parse_flag>1</exclude_from_parse_flag>
</capacity>