Я искал различные способы конвертировать шесть 20 МБ .log файлов в .xml
Люди отсылают меня к онлайн-конвертерам, которые не конвертируют.
Другие говорят, что использовать инструмент разработчика EXCEL, но
Данные не в правильном формате
Занимает навсегда скопировать и вставить 20 МБ данных на EXCEL.
Я думаю о двух вариантах:
В powershell сохраните каждую строку в виде массива, а затем для массива досягаемости линий создайте другой массив, но форматы строк, как вы увидите, не согласованы
Узнайте, как использовать php или python для преобразования в xml
Вот формат данных
06/01 01:25:58 [2024:2588] 10.4.10.10<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="MYAWESOMEDOMAIN.ORG" LoginUser="admIN" ComputerDomain="myAWESOMEDOMAIN.org" ComputerName="AWESOMES001" PreferredGroup="My%20Company%5cServers%5cGUP" PreferredMode="1" KnownClientID="C35A5B1E0AFB16760019AE74888EA38A" HardwareKey="46E04E5469DC41949F33E73FDC0C5FCF" IsNPVDIClient="0" SiteDomainName=""/>
06/01 01:26:07 [2024:3280] 10.24.10.97<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="LocalComputer" LoginUser="Student%208" ComputerDomain="WORKGROUP" ComputerName="DC9Spartan" PreferredGroup="My%20Company%5cDefault%20Group" PreferredMode="1" HardwareKey="208B60B45CE2D02192B2FBB30CA1470A" SiteDomainName=""/>
06/01 01:26:07 [2024:3280] 10.24.10.97<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="LocalComputer" LoginUser="Student%208" ComputerDomain="WORKGROUP" ComputerName="DC9Spartan" PreferredGroup="My%20Company%5cDefault%20Group" PreferredMode="1" HardwareKey="208B60B45CE2D02192B2FBB30CA1470A" SiteDomainName=""/> AgentID=2C26221A0AFB167201AE7F6B29E365AD AgentType=105 ComputerID=1E6BFEF50AFB167201AE7F6BBA576A0C Hash Key=69C6250108E5B7FBB6ACF8294B6564FE
06/01 01:26:19 [2024:2748] 10.21.36.6<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="LocalComputer" LoginUser="student" ComputerDomain="WORKGROUP" ComputerName="DingDing9461JZ6" PreferredGroup="My%20Company%5cDefault%20Group" PreferredMode="1" HardwareKey="C6D4F00C9C2952182D8DAB03045C6E30" SiteDomainName=""/>
06/01 01:26:19 [2024:2748] 10.21.36.6<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="LocalComputer" LoginUser="student" ComputerDomain="WORKGROUP" ComputerName="DingDing9461JZ6" PreferredGroup="My%20Company%5cDefault%20Group" PreferredMode="1" HardwareKey="C6D4F00C9C2952182D8DAB03045C6E30" SiteDomainName=""/> AgentID=BBF24AB00AFB167200D94A8E46E57D3C AgentType=105 ComputerID=1B4EF5B30AFB167200D94A8E8EBB8E65 Hash Key=6BAC96603C7495DE08E5F305EEF310EE
06/01 01:26:33 [2024:3376] 5 Server returned: 500 Internal Server Error
06/01 01:26:33 [2024:3376] 10.16.64.16<AgentInfo DomainID="ACD6E7230AFB160401B335F917AFF5BE" AgentType="105" UserDomain="LocalComputer" LoginUser="admin" ComputerDomain="myAWESOMEDOMAIN.org" ComputerName="LLR0MGVY" PreferredGroup="My%20Company%5cDefault%20Group" PreferredMode="1" HardwareKey="EFDBD800D66488B08936A51F19B5496A" IsNPVDIClient="0" SiteDomainName=""/>--FAILED
Я пытаюсь сопоставить IP-адрес с другими данными, такими как DomainID
, так далее.
Это усложняется тем, что есть строка с некоторым сообщением об ошибке сервера, а затем строка NEXT перечисляет IP-адрес,
Я думаю, что если я смогу перейти в формат XML, было бы проще запрашивать данные. Или есть другой подход для достижения того, что я пытаюсь сделать?
Спасибо
Я не слишком знаком с XML, но думаю, что вывод, который я ищу,
<Date>06/01 01:25:58
<ID>[2024:2588]
<IP>10.4.10.10</IP>
<AgentInfo>
<DomainID></DomainID>
<AgentType></AgentType>
<UserDomain></UserDomain>
<LoginUser></LoginUser>
etc, etc, the other fields within AgentInfo
</AgentInfo>
</ID>
</Date>
<Date>06/01 01:26:33
<ID>[2024:3376]
<IP>10.16.64.16</IP>
<Msg>5 Server returned: 500 Internal Server Error</Msg>
</ID>
</Date>
Я предложу решение PowerShell с использованием RegEx, ConvertFrom-StringData
(возможно, мог бы использовать XML-типизацию для преобразования AgentInfo, но для моего решения это было проще) и HashTable объектов для сбора записей в объекты, затем я преобразовал это в XML и очистил его, потому что PowerShell ConvertTo-XML
Командлет является слишком многословным imho.
$InputData = Get-Content 'C:\Path\To\File.log'
$Records = @{}
$InputData | ?{$_ -match "^(?<Date>\d{2}\/\d{2} \d{2}:\d{2}:\d{2}) (?<ID>\[.+?\]) (?<IP>\S+)\<AgentInfo (?<AgentInfo>.+?)\/\>" -or $_ -match "^(?<Date>\d{2}\/\d{2} \d{2}:\d{2}:\d{2}) (?<ID>\[.+?\]) (?<Msg>.+)"}|
%{$Record = [pscustomobject]@{
[string]'Date'=$Matches['Date']
[string]'ID'=$Matches['ID']
[string]'IP'=$Matches['IP']
[string]'Msg'=$Matches['Msg']
'AgentInfo'=New-Object PSObject -Prop ($Matches['AgentInfo'] -replace '(?<=") ',"`r`n" | ConvertFrom-StringData)
}
$record
If($Matches['ID'] -notin $Records.Keys){
$Records.Add($Matches['ID'], $Record)
}Else{
$Record|Get-Member -MemberType Properties | Where{![string]::IsNullOrEmpty($Record.($_.Name))} | ForEach{$Records."$($Matches['ID'])"|Add-Member "$($_.Name)" $Record.$($_.Name) -Force}
}
}
$records.Values|select Date,ID,IP,Msg,AgentInfo|convertto-xml -Depth 2 -NoTypeInformation -as Stream|%{$_ -replace 'Property Name="(.+?)(?=">)"(.*)Property(?=>)','$1$2$1' -replace 'Property Name="(.+?)"(?= />)','$1' -replace '<Property Name="(.+?)">','<$1>' -replace '</Property>','</AgentInfo>'} | Set-Content C:\Path\To\OutFile.xml
Это будет выводить:
<?xml version="1.0"?>
<Objects>
<Object>
<Date>06/01 01:26:19</Date>
<ID>[2024:2748]</ID>
<IP>10.21.36.6</IP>
<Msg />
<AgentInfo>
<LoginUser>"student"</LoginUser>
<ComputerDomain>"WORKGROUP"</ComputerDomain>
<ComputerName>"DingDing9461JZ6"</ComputerName>
<DomainID>"8CB49C910AFB16720044B53CD014E7D9"</DomainID>
<HardwareKey>"C6D4F00C9C2952182D8DAB03045C6E30"</HardwareKey>
<SiteDomainName>""</SiteDomainName>
<PreferredGroup>"My%20Company%5cDefault%20Group"</PreferredGroup>
<AgentType>"105"</AgentType>
<PreferredMode>"1"</PreferredMode>
<UserDomain>"LocalComputer"</UserDomain>
</AgentInfo>
</Object>
<Object>
<Date>06/01 01:25:58</Date>
<ID>[2024:2588]</ID>
<IP>10.4.10.10</IP>
<Msg />
<AgentInfo>
<LoginUser>"admIN"</LoginUser>
<IsNPVDIClient>"0"</IsNPVDIClient>
<ComputerDomain>"myAWESOMEDOMAIN.org"</ComputerDomain>
<ComputerName>"AWESOMES001"</ComputerName>
<DomainID>"8CB49C910AFB16720044B53CD014E7D9"</DomainID>
<HardwareKey>"46E04E5469DC41949F33E73FDC0C5FCF"</HardwareKey>
<SiteDomainName>""</SiteDomainName>
<PreferredGroup>"My%20Company%5cServers%5cGUP"</PreferredGroup>
<AgentType>"105"</AgentType>
<KnownClientID>"C35A5B1E0AFB16760019AE74888EA38A"</KnownClientID>
<PreferredMode>"1"</PreferredMode>
<UserDomain>"MYAWESOMEDOMAIN.ORG"</UserDomain>
</AgentInfo>
</Object>
<Object>
<Date>06/01 01:26:07</Date>
<ID>[2024:3280]</ID>
<IP>10.24.10.97</IP>
<Msg />
<AgentInfo>
<LoginUser>"Student%208"</LoginUser>
<ComputerDomain>"WORKGROUP"</ComputerDomain>
<ComputerName>"DC9Spartan"</ComputerName>
<DomainID>"8CB49C910AFB16720044B53CD014E7D9"</DomainID>
<HardwareKey>"208B60B45CE2D02192B2FBB30CA1470A"</HardwareKey>
<SiteDomainName>""</SiteDomainName>
<PreferredGroup>"My%20Company%5cDefault%20Group"</PreferredGroup>
<AgentType>"105"</AgentType>
<PreferredMode>"1"</PreferredMode>
<UserDomain>"LocalComputer"</UserDomain>
</AgentInfo>
</Object>
<Object>
<Date>06/01 01:26:33</Date>
<ID>[2024:3376]</ID>
<IP>10.16.64.16</IP>
<Msg>5 Server returned: 500 Internal Server Error</Msg>
<AgentInfo>
<LoginUser>"admin"</LoginUser>
<IsNPVDIClient>"0"</IsNPVDIClient>
<ComputerDomain>"myAWESOMEDOMAIN.org"</ComputerDomain>
<ComputerName>"LLR0MGVY"</ComputerName>
<DomainID>"ACD6E7230AFB160401B335F917AFF5BE"</DomainID>
<HardwareKey>"EFDBD800D66488B08936A51F19B5496A"</HardwareKey>
<SiteDomainName>""</SiteDomainName>
<PreferredGroup>"My%20Company%5cDefault%20Group"</PreferredGroup>
<AgentType>"105"</AgentType>
<PreferredMode>"1"</PreferredMode>
<UserDomain>"LocalComputer"</UserDomain>
</AgentInfo>
</Object>
</Objects>
Это довольно близко к тому, что вы хотели получить в качестве результата.
Я бы точно использовал Python.
Что-то вроде этого:
import sys
inFile = sys.argv[1]
inFile = open(inFile,'r')
parser = inFile.readlines()
outFile = open('[your_path]\\converted.xml', 'w')
for i in parser:
slice = i.split(' ') #split each line at spaces and do stuff with each slice
outFile.write("<date>" + slice[0] + "</date>" + '\n')
outFile.write("<time>" + slice[1] + "</time>" + '\n')
and so on...
XMLWriter Api — это XML Api, разработанный для такой работы. Вот пример для начала:
$xml = new XMLWriter();
$xml->openUri($output);
$xml->startDocument();
$xml->setIndent(2);
$xml->startElement('log');
$file = fopen($input, 'r');
while (FALSE !== ($line = fgets($file))) {
if (FALSE !== ($p = strpos($line, '<'))) {
$xml->startElement('line');
$xml->writeElement('date', substr($line, 0, $p - 1));
$xml->writeRaw(substr($line, $p));
$xml->endElement();
}
}
$xml->endElement();
$xml->endDocument();
$xml->flush();
Выход:
<?xml version="1.0"?>
<log>
<line>
<date>06/01 01:25:58 [2024:2588] 10.4.10.1</date>
<AgentInfo DomainID="8CB49C910AFB16720044B53CD014E7D9" AgentType="105" UserDomain="MYAWESOMEDOMAIN.ORG" LoginUser="admIN" ComputerDomain="myAWESOMEDOMAIN.org" ComputerName="AWESOMES001" PreferredGroup="My%20Company%5cServers%5cGUP" PreferredMode="1" KnownClientID="C35A5B1E0AFB16760019AE74888EA38A" HardwareKey="46E04E5469DC41949F33E73FDC0C5FCF" IsNPVDIClient="0" SiteDomainName=""/>
</line>
...
Вам понадобится элемент документа и элементы для каждой записи / строки, это хорошая идея. Я разделил это только на две основные части. Вам нужно будет добавить больше логики (возможно, Regex) в зависимости от целевого формата XML. Информация об агенте является элементом / документом XML, поэтому ее можно скопировать (необработать) в целевой XML.
XMLWriter не является эксклюзивным API для PHP, вы найдете реализации для многих языков.