Powershell - поиск 2 значений в. xml файле с регулярным выражением - PullRequest
1 голос
/ 15 апреля 2020

Я надеюсь, что вы хорошо в этой конкретной ситуации.

Описание запроса: чтобы упростить мою жизнь в повседневной жизни, я пытаюсь написать сценарий powershell, цель которого состоит в том, чтобы найти каждую таблицу «Name», в которой «зарезервированный» размер> 1G

Ниже приведен пример вывода, который я хочу получить на основе xml образца файла ниже

Вывод

  • Имя таблицы: tr_stat_history
  • Размер таблицы : 3,829623 ГБ

  • Имя таблицы: appctrl_exefile

  • Размер таблицы: 1,58016 ГБ

xml file пример

<?xml version="1.0" encoding="utf-8" ?>
<data>
<record>
<field value="tr_stat_history" name="Name"/>
<field value="1024936 " name="Rows"/>
<field value="3829623 KB" name="reserved"/>
<field value="38120 KB" name="Data"/>
<field value="120 KB" name="index_size"/>
<field value="56 KB" name="Unused"/>
</record>
<record>
<field value="appctrl_exefile" name="Name"/>
<field value="2149679 " name="Rows"/>
<field value="1580160 KB" name="reserved"/>
<field value="120376 KB" name="Data"/>
<field value="37336 KB" name="index_size"/>
<field value="304 KB" name="Unused"/>
</record>
<record>
<field value="appctrl_pdffile" name="Name"/>
<field value="2149 " name="Rows"/>
<field value="1580 KB" name="reserved"/>
<field value="1203 KB" name="Data"/>
<field value="3733 KB" name="index_size"/>
<field value="508 KB" name="Unused"/>
</record>
</data>

Что может быть лучшим способом для достижения моей цели?

Заранее спасибо,

Ответы [ 3 ]

2 голосов
/ 15 апреля 2020

Вместо использования регулярных выражений, вы можете захотеть приблизиться к этому, используя возможности разбора Powershell xml.

Я не в курсе того, как лучше всего использовать xml, поэтому у следующих, несомненно, есть место для улучшения, но вы можете понять его с помощью следующего примера.

(
    [xml]@'
    <root>
        <record>
            <field value="tr_stat_history" name="Name"/>
            <field value="1024936 " name="Rows"/>
            <field value="3829623 KB" name="reserved"/>
            <field value="38120 KB" name="Data"/>
            <field value="120 KB" name="index_size"/>
            <field value="56 KB" name="Unused"/>
        </record>
        <record>
            <field value="appctrl_exefile" name="Name"/>
            <field value="2149679 " name="Rows"/>
            <field value="1580160 KB" name="reserved"/>
            <field value="120376 KB" name="Data"/>
            <field value="37336 KB" name="index_size"/>
            <field value="304 KB" name="Unused"/>
        </record>
        <record>
            <field value="appctrl_pdffile" name="Name"/>
            <field value="2149 " name="Rows"/>
            <field value="1580 KB" name="reserved"/>
            <field value="1203 KB" name="Data"/>
            <field value="3733 KB" name="index_size"/>
            <field value="508 KB" name="Unused"/>
        </record>
    </root>
'@
).root.record | % {if (([int]($_.Field[2].Value -split ' ')[0])*1024 -gt 1GB) {$_.Field[0].Value}}

, где

  • Я добавил элемент root, чтобы иметь действительный xml
  • Приведите строку a [xml] type
  • L oop по всем record элементам с помощью %
  • Проверьте поле reserved. Поскольку значение содержит строку, я разделил ее на пробел, взял первый элемент полученного массива, бросил его как целое число и умножил на 1024. После этого это просто сравнить с 1GB
  • Только если поле reserved> 1 ГБ, поле name получает вывод
1 голос
/ 15 апреля 2020

Оба решения потрясающие! Спасибо за вашу помощь !

Я использую следующее:

# Create XML object to load data into
$xml = New-Object -TypeName System.Xml.XmlDocument

$ResultXMLfile = Read-Host "Path to result.xml"

# Load in XML file
$xml.Load($ResultXMLfile)

# Iterate each child node underneath the data tag
foreach ($node in $xml.data.ChildNodes)
{
    # Get name and reserved fields
    $name = $node.field | Where-Object {$_.name -eq "Name"}
    $reserved = $node.field | Where-Object {$_.name -eq "reserved"}

    # Split on whitespace and take the digit
    # Do KB conversion to bytes by multiplying by 1024
    $kb = [long]$reserved.Value.Split(' ')[0] * 1024

    # Check if bigger than 1GB or 1073741824 bytes
    # Output table name and size if this is true
    if ($kb -gt 1GB)
    {
        Write-Output "Table name: $($name.Value)"
        Write-Output "Table size: $($kb / 1GB) GB"
    }
}

В моем случае мой xml содержит 35 тыс. Строк, поэтому через несколько секунд я получил свой ответ.

Path to result.xml : C:\Users\Usernames\Desktop\Download\all_result\all_result\result.xml
Table name: appctrl_exefile_hst
Table size: 2.74079895019531 GB
Table name: nl_storage_items
Table size: 2.76924133300781 GB
0 голосов
/ 15 апреля 2020

Вот еще один подход, который вы можете попробовать. Я добавил комментарии, чтобы объяснить логи c.

# Create XML object to load data into
$xml = New-Object -TypeName System.Xml.XmlDocument

# Load in XML file
$xml.Load("input.xml")

# Iterate each child node underneath the data tag
foreach ($node in $xml.data.ChildNodes)
{
    # Get name and reserved fields
    $name = $node.field | Where-Object {$_.name -eq "Name"}
    $reserved = $node.field | Where-Object {$_.name -eq "reserved"}

    # Split on whitespace and take the digit
    # Do KB conversion to bytes by multiplying by 1024
    $kb = [long]$reserved.Value.Split(' ')[0] * 1024

    # Check if bigger than 1GB or 1073741824 bytes
    # Output table name and size if this is true
    if ($kb -gt 1GB)
    {
        Write-Output "Table name: $($name.Value)"
        Write-Output "Table size: $($kb / 1GB) GB"
    }
}

Вывод:

Table name: tr_stat_history
Table size: 3.65221309661865 GB
Table name: appctrl_exefile
Table size: 1.5069580078125 GB
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...