次のような多くの行を含むログファイルがあります。
2021/09/03-13:11:05;QUEUE.INBOUND;4;ID:myhost.mydomain.net-7756-1629822315072-199:973:1:1:1;MISC;"<?xml version="1.0" encoding="UTF-8"?> <RootElement xmlns="urn:namespace:entity/1" tstamp="2021-02-29T12:11:00Z" object="urn:domain:entity:ID1234"><Active lang="en" value="true">active</Active><Name lang="en">Some Name</Name><ShortName lang="en">shortname</ShortName><Phone number="+416458838829" lang="en">+416458838829</Phone><Email>[email protected]</Email><Longitude>7.043786</Longitude><Latitude>47.239036</Latitude></RootElement>"
(XMLはこれより大きいですが、これは単なる例です。)
私の目標は、各行の各XMLを専用ファイルに抽出することです。ログに10行が含まれていると、10個のファイルが生成されます。
これが私が始めた方法です。
more mylogfile.txt | sed -r 's!^.*\s(<RootElement.*\sobject="urn:domain:entity:([A-z0-9]*)"><Active.*</RootElement>).*!echo "\1" | xmlstarlet fo > "\2.xml"!e; d'
アイデアは、オブジェクトの瓶からIDを抽出してファイル名として使用することです(IDはファイル内で一意です)。
質問:
「echo」コマンドのみを実行する場合
more mylogfile.txt | sed -r 's!^.*\s(<RootElement.*\sobject="urn:domain:entity:([A-z0-9]*)"><Active.*</RootElement>).*!echo "\1"!e; d'
XMLの二重引用符が消去され、最初の試行でコマンドでxmlstarlet
エラーが発生したことがわかりました。
アクティブ要素の例は次のとおりです。
<Active lang=en value=true>active</Active>
sed
bashコマンドinとoutを実行すると、構文にいくつかのトリックがあることがわかりましたが、いくつかの他の構文(たとえば、\ 1の周りの ""を削除する、代わりに外部使用など)をecho
試しましたが、何も試みませんでした。働いた。printf
xargs
sed
私はUbuntuディストリビューション18.04(WindowsではWSL 1)を使用しています。
echo
sed
s!...!...!e
それとも、 ""コマンドにこの問題を改善するオプションはありますか?
(より効率的な方法を見つけたら私もそうします)
答え1
まず、エスケープされた引用符を使用する必要がありますs/"/\\"/g
。これにより食べることができなくなりますecho
。
その後、検索パターンを調整することを忘れないでください。\"
代わりに一致し、バックスラッシュをエスケープする必要があるため、検索パターンに配置する"
必要があります。\\"
sed -E 's/"/\\"/g;s!^.*\s(<RootElement.*\sobject=\\"urn:domain:entity:([A-Za-z0-9]*)\\"><Active.*</RootElement>).*!echo "\1"!e;d'