あるファイルから文字列を抽出して別のファイルに挿入(修正)するには?

あるファイルから文字列を抽出して別のファイルに挿入(修正)するには?

質問は次のとおりです。

データを含むxmlファイルがあり、新しいファイルに書き込むデータの小さな部分を探しています。リクエストによりコンテンツが短縮されました。

type=dhcp-client の場合、コードスニペットは次のようになります。

    <deviceconfig>
      <system>
        <type>
          <dhcp-client>
            <send-hostname>yes</send-hostname>
          </dhcp-client>
        </type>
        <hostname>Firewall</hostname>
      </system>
    </deviceconfig>

タイプ=静的であれば断片化

    <deviceconfig>
      <system>
        <type>
          <static/>
        </type>
        <hostname>Firewall</hostname>
        <permitted-ip>
          <entry name="192.168.0.0/24"/>
        </permitted-ip>
        <ip-address>192.168.0.2</ip-address>
        <netmask>255.255.255.0</netmask>
        <default-gateway>192.168.0.1</default-gateway>
      </system>
    <network>
      <interface>
        <ethernet>
          <entry name="ethernet1/1">
            <layer3>
              <ip>
                <entry name="192.168.0.5/24"/>
              </ip>
            </layer3>
          </entry>
        </ethernet>
      </interface>
      <virtual-router>
        <entry name="default">
          <routing-table>
            <ip>
              <static-route>
                <entry name="default-route">
                  <nexthop>
                    <ip-address>192.168.0.1</ip-address>
                  </nexthop>
                  <interface>ethernet1/4</interface>
                  <destination>0.0.0.0/0</destination>
                </entry>
              </static-route>
            </ip>
          </routing-table>
        </entry>
      </virtual-router>
    </network>

4つの関連値は、「システム」タグ内に一意または存在しません。 <system></system> IP アドレスのようなものは、システムの外部の他の場所に再び表示されることがありますが、 <system></system> タイプが次の場合にのみシステム内部の値を確認します。静的ではないので表示されません。 DHCPクライアントとして設定します。

タイプがdhcpの場合、必要なファイルの結果は次のとおりです。

type=dhcp-client

タイプが静的な場合、ファイルに必要な結果は次のとおりです。

type=static
ip-address=192.168.0.2
default-gateway=192.168.0.1
netmask=255.255.255.0

これを効率的に実行し、既存のシステムに統合する方法がわかりません。PHPファイルに保存します(したがって作業するには、execを使用するか、単にphpを使用することをお勧めします)。

また、Ubuntuサーバーシステムにデフォルトでインストールされているツールのみが利用可能で、他のパッケージは利用できません。

PS:これは実際には完全/完全なユースケースなので、これら2つの例外に別の出力を生成する必要はありません。助けやアドバイスをありがとうございます:)

ベストアンサー1

XML認識ツールにアクセスできず、入力ファイルが表示されているように単純で規則的であると仮定すると、公開された入力例に基づいて予想される出力が生成されます。

$ cat tst.awk
BEGIN { FS="[[:space:]]*[<>][[:space:]]*"; OFS="=" }
$2 == "system"  { inBlock=1 }
inBlock { f[$2] = $3 }
$2 == "/system" { inBlock=0 }
END {
    if ("ip-address" in f) {
        print "type", "static"
        print "ip-address", f["ip-address"]
        print "default-gateway", f["default-gateway"]
        print "netmask", f["netmask"]
    }
    else {
        print "type", "dhcp-client"
    }
}

$ awk -f tst.awk absentFile
type=dhcp-client

$ awk -f tst.awk presentFile
type=static
ip-address=192.168.0.2
default-gateway=192.168.0.1
netmask=255.255.255.0

上記は以下の入力ファイルで実行されました。

$ tail -n +1 absentFile presentFile
==> absentFile <==
    <deviceconfig>
      <system>
        <type>
          <dhcp-client>
            <send-hostname>yes</send-hostname>
          </dhcp-client>
        </type>
        <hostname>Firewall</hostname>
      </system>
    </deviceconfig>

==> presentFile <==
    <deviceconfig>
      <system>
        <type>
          <static/>
        </type>
        <hostname>Firewall</hostname>
        <permitted-ip>
          <entry name="192.168.0.0/24"/>
        </permitted-ip>
        <ip-address>192.168.0.2</ip-address>
        <netmask>255.255.255.0</netmask>
        <default-gateway>192.168.0.1</default-gateway>
      </system>
    <network>
      <interface>
        <ethernet>
          <entry name="ethernet1/1">
            <layer3>
              <ip>
                <entry name="192.168.0.5/24"/>
              </ip>
            </layer3>
          </entry>
        </ethernet>
      </interface>
      <virtual-router>
        <entry name="default">
          <routing-table>
            <ip>
              <static-route>
                <entry name="default-route">
                  <nexthop>
                    <ip-address>192.168.0.1</ip-address>
                  </nexthop>
                  <interface>ethernet1/4</interface>
                  <destination>0.0.0.0/0</destination>
                </entry>
              </static-route>
            </ip>
          </routing-table>
        </entry>
      </virtual-router>
    </network>

おすすめ記事