Unixコマンドを使用して `xml`で空のタグを見つける

Unixコマンドを使用して `xml`で空のタグを見つける

生成されたファイルには、xml次のように空のタグがあります。

<headertag>
</headertag>

連続した行にあり、タグ間の改行文字をパターン(\ n)で基づいて見つけるために通常Perlスクリプトを使用しますが、現在使用しているUnix環境ではこのPerlスクリプトをサポートしていません。 sedを使用して同じ操作を試みましたが、.xml大きなファイルにこれらの空白マークがある場所(行番号)が見つかりませんでした。sedまたはを使用してこれを見つけるためのソリューションはありますかawk

答え1

XMLを解析するには、XML対応ツールを使用します。使用しているシステムに制限があると言われていることがわかります。ただし、強力で信頼性の高い作業に必要なすべてを管理者に説得すると、機能するソリューションが提供されます。 XML解析を正しく実行するには、XMLStarletをインストールする必要があります。

指定されたXMLファイルでXMLStarletを使用する

<?xml version="1.0"?>
<root>
  <headertag>
    <subtag/>
  </headertag>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
</headertag>
  <headertag>
Not empty
</headertag>
</root>

以下は、名前や文書に表示される場所に関係なく、すべての空のタグを削除します。

$ xmlstarlet ed -d '//*[not(normalize-space())]' file.xml >newfile.xml

$ cat newfile.xml
<?xml version="1.0"?>
<root>
  <headertag>
    <subtag>Don't delete me!</subtag>
  </headertag>
  <headertag>
Not empty
</headertag>
</root>

このコマンドは、システムにパッケージされた方法に従ってxmlstarlet呼び出すこともできます。xml

XMLStarletはここで利用可能です:http://xmlstar.sourceforge.net/ ...しかし、まずデフォルトのパッケージマネージャにその機能があることを確認してください。

答え2

仮定:

  • 私たちが探している空のタグはそれ自体一行にあります。
  • 閉じるタグも独自の行にあり、すぐに続いています。
  • スペースはタブではなくスペースで構成されていると見なされます。

sed -ne '
   /^ *\(<[^><]*>\) *$/!d                                   # tag opening should be on a line of its own
   s//\1/                                                   # strip away all whitespace
   $d; N                                                    # if the tag opening is on the last line, we dont need it. Otherwise, we grab the next line
   s/^.\(.*\).\n *<\/\1> *$/Empty tag: <\1> on line num\#/p # print only in case the tagnames match across lines => we have found an empty tag
   /\n/!=                                                   # print empty tag line num
   D                                                        # delete the pattern space
' yourfile.xml

答え3

空のタグの処理方法を教えてくれませんでした。したがって、これらのタグのペアを次の形式に変換したいとします。<headertag/>

sed以下は、あなたが提供した例の例について正確にそのタスクを実行する簡単なスクリプトです。

sed -E ':a;N;$!ba;s#<([^>]+)>\n</\1>#<\1/>#g' infile > outfile

答え4

grepの代わりに「pcregrep」を使用でき、複数行モードをサポートし、より多くのオプションがあります。

このパターンは、開始タグと終了タグを含む2つの連続した行を探します。

pcregrep -M -v "<headertag>\n\s*?</headertag>" file
  • ここで、-M は複数行を表します。
  • -v は逆方向一致を示します。
  • \n は pcregrep ではサポートされているが grep ではサポートされない改行文字です。
  • \ sは空白文字です。
  • *?すべての文字

このモードは空のタグをすべて削除します。

関連情報