私の状況は、内容が以下のようになりますが、より長いファイルがあるということです。https://pastebin.com/q33wFdAX
次の項目をすべて削除する必要があります。
<category>Games</category>
</game>
カテゴリにデータがある場合は削除したくありません。したがって、デフォルトでは、grep -vなど、この二重線を正確に一致させ、逆にすることができれば、その行なしで新しいファイルに出力できます。
私はこのカテゴリよりも多くを持っているので、複数またはドアを使用できるはずです。この操作を手動で実行するためにメモ帳++で使用した正規表現の例
(^\s+<category>Games</category>\s+</game>$|^\s+<category>Applications</category>\s+</game>$)
Powershellでこれを簡単に行う方法を教えてください。両方のオペレーティングシステムでこれを行うことができれば幸いです。私は上級正規表現、awkなどに精通していません。
答え1
与えられたこれオリジナル文書次のように、(USA)
タイトルノードのプロパティrom
に記載されていないすべてのタイトルを削除しますname
。
xmlstarlet ed -d '//game[not(contains(rom/@name, "(USA)"))]' file-orig.xml >file-new.xml
XPath式は、次の属性を持つ1つ以上の子ノードを持つすべてのノードを//game[not(contains(rom/@name, "(USA)"))]
選択します。game
rom
name
いいえ文字列を含みます(USA)
。削除のために選択されました。
コマンドラインからリダイレクトを使用して、出力を新しいファイルに書き込みます。
XMLデータを簡単に見た後、ノードを見る必要はなく、プライマリノードのプロパティだけを見るだけでrom
十分です。game
name
xmlstarlet ed -d '//game[not(contains(@name, "(USA)"))]' file-orig.xml >file-new.xml
(USA)
これにより、ノード属性に含まれていないすべてのゲームが削除されます。name
game
タイトル以外のすべてのアイテムを削除すると、ダウンロードしたファイルに1979件のタイトルが含まれます(USA)
。
カテゴリ以外のすべてのアイテムをさらにフィルタリングするには、次の手順を実行しますGames
。
xmlstarlet ed \
-d '//game[not(contains(@name, "(USA)"))]' \
-d '//game[category != "Games"]' file-orig.xml >file-new.xml
これで1474のゲームタイトルが残ります。
楽しみのために、ゲームのタイトルの総数に応じてゲームのタイトルを並べ替えてください。サイズ:
xmlstarlet ed \
-d '//game[not(contains(@name, "(USA)"))]' \
-d '//game[category != "Games"]' file-orig.xml |
xmlstarlet sel -t -m '//game' \
-v 'sum(rom/@size)' -o ' ' -v '@name' -nl | sort -n