큰 SMS 메시지 XML 파일이 있습니다. 쉽게 접근할 수 있는 csv 형식으로 만들고 싶습니다. 나는 "address", "messageBody" 및 "messageTime" 부분을 구체적으로 추출하려고 시도했지만 성공하지 못했습니다.
<messageType>1</messageType><messageTime>1624297248761</messageTime><read>null</read><status>null</status><service_center>null</service_center><person>null</person><seen>1</seen></chat><chat><threadID>50</threadID><address>447917504050</address><messageBody>Yeah mate let's do lunch and catch up.</messageBody><messageType>1</messageType><messageTime>1629944007697</messageTime><read>null</read><status>null</status><service_center>null</service_center><person>null</person><seen>1</seen></chat><chat><threadID>50</threadID><address>447917563330</address><messageBody>You going now mate</messageBody>
나는 다음과 같은 작은 성공을 거두었습니다.
cat SMS.xml | awk -F'address' '{print $2}'
그러나 이것은 줄의 첫 번째 "주소"만 가져오고 나머지는 무시합니다.
이 데이터를 읽을 수 있는 csv 형식으로 변환하는 방법에 대한 아이디어가 있습니까?
"messageTime" 섹션의 숫자를 설명하는 데 도움을 주시면 대단히 감사하겠습니다.
편집: 실제 xml 파일에는 균형 잡힌 열기 및 닫기 태그가 있으며 형식이 올바르게 지정되었습니다. 여기서는 일부 내용을 발췌했습니다.
답변1
XML의 형식이 올바르고 모든 노드가 일부 단일 노드 아래에 chat
나타난다 고 가정하면 ( ,root
xq
yq
https://kislyuk.github.io/yq/):
xq -r '["address","messageBody","messageTime"], (.root.chat[] | [.address,.messageBody,.messageTime]) | @csv' file.xml
누락된 시작 및 종료 태그를 추가하여 질문의 손상된 XML을 수정하면 다음과 같은 CSV 출력이 생성됩니다.
"address","messageBody","messageTime"
,,"1624297248761"
"447917504050","Yeah mate let's do lunch and catch up.","1629944007697"
"447917563330","You going now mate",
답변2
다른xmlstarlet쉼표로 구분된 데이터 출력에 대한 답변:
xmlstarlet sel -t -m //chat -v messageTime -o , -v address -o , -v messageBody -n file.xml
1624297248761,,
1629944007697,447917504050,Yeah mate let's do lunch and catch up.
,447917563330,You going now mate
배치 메시지 본문입니다.마지막이 쉼표로 구분된 데이터는 끝까지 세 번째 필드를 본문으로 갖습니다.
메시지 시간은 1970-01-01 00:00:00 UTC 이후의 밀리초 수입니다. 이를 처리하는 한 가지 방법은 GNU awk를 사용하는 것입니다.
xmlstarlet sel -t -m //chat -v messageTime -o , -v address -o , -v messageBody -n file.xml \
| TZ=UTC gawk 'BEGIN {FS = OFS = ","} {$1 = strftime("%F %T", $1 / 1000)} 1'
산출
2021-06-21 17:40:48,,
2021-08-26 02:13:27,447917504050,Yeah mate let's do lunch and catch up.
1970-01-01 00:00:00,447917563330,You going now mate
이 형식을 사용하면 시간순으로 쉽게 정렬할 수 있습니다.
답변3
주석에서 언급한 대로 XML이 올바르지 않으므로 다음과 같이 모든 텍스트를 새 태그로 묶습니다.
<?xml version="1.0"?>
<myxml>
<chat>
....your data which already includes </chat><chat>
</chat>
</myxml>
그런 다음 다음과 같이 사용할 수 있습니다 xmlstarlet
(예: 주소를 가져오는 데).
xmlstarlet select --template --value-of /myxml/chat/address --nl input_file.xml
( input_file.xml
위와 같이 추가 라벨이 있는 데이터를 포함해야 함)
더 많은 예시여기