awk、grep、および/またはpowershellを使用して複数行をフィルタリングする方法

awk、grep、および/またはpowershellを使用して複数行をフィルタリングする方法

私の状況は、内容が以下のようになりますが、より長いファイルがあるということです。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)"))]選択します。gameromnameいいえ文字列を含みます(USA)。削除のために選択されました。

コマンドラインからリダイレクトを使用して、出力を新しいファイルに書き込みます。

XMLデータを簡単に見た後、ノードを見る必要はなく、プライマリノードのプロパティだけを見るだけでrom十分です。gamename

xmlstarlet ed -d '//game[not(contains(@name, "(USA)"))]' file-orig.xml >file-new.xml

(USA)これにより、ノード属性に含まれていないすべてのゲームが削除されます。namegame

タイトル以外のすべてのアイテムを削除すると、ダウンロードしたファイルに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

関連情報