如何根据两个单独CSV之间的匹配字段向CSV添加字段?

时间:2016-03-16 17:44:29

标签: csv powershell logging

我正在尝试将包含URL和IP地址的一个日志文件中的URL与仅包含IP地址的另一个文件进行匹配。每个文件的示例日志如下所示:

包含网址的文件:

Date;Time;Source;Destination;Port;User;URL
3/7/2016;0:00:07;168.254.25.6;10.0.1.27;80;jsmith;abcnet

将网址添加到的文件:

Date;Time;Source;Destination;Port;User;URL
3/7/2016;0:00:09;168.254.25.6;10.0.1.27;80;;

我正在尝试编写一个脚本来确定目标字段对于两个文件之间的任何日志是否相同,如果是,则将URL的值分配给缺少URL的日志中的该IP地址。我编写了以下两个脚本来尝试这样做。第一个查找URL到IP地址的所有映射,而第二个应该使用此列表填充URL字段。但是,我得到第一个脚本的空白输出,所以我甚至无法使用结果来测试第二个脚本。

将每个IP地址映射到URL的代码:

$urlMissing  = Import-Csv C:\Path\to\firstLog.csv -Delimiter ';' |
               Select-Object -Unique Destination
$urlExisting = Import-Csv C:\path\to\SecondLog.csv -Delimiter ';' |
               Select-Object Destination, URL
$result      = "C:\path\to\result.csv"

if (Test-Path $result) {
    Remove-Item $result
}

$urlMissing | Add-Member -MemberType NoteProperty -Name URL -Value $null

foreach ($line in $urlMissing) {
    $cpDest = $line.Destination
    $returnRecords = $urlExisting | Where-Object {$_.Destination -eq $cpDest}

    $destURL = $returnRecords.URL | Select-Object -Unique

    if ($destURL -ne $null) {
        if ($destURL.Count -gt 1) {
            $destURL = $destURL -join ';'
        }
    }
    $line.URL = $destURL
}

$urlMissing | Export-Csv $result

将第一个脚本的结果添加到缺少URL的日志文件的代码:

$missingURL = Import-Csv C:\Path\to\missingURL.csv
$result     = "C:\Path\to\result.csv"
$urlsFound  = Import-Csv C:\Path\to\result.csv

if (Test-Path $result) {
    Remove-Item $result
}

foreach ($line in $missingURL) {
    $cpDest = $line.Destination

    $returnRecords = $urlsFound | Where-Object {$_.Destination -eq $cpDest}

    if ($cpDest -eq $returnRecords.Destination) {
        $line.URL = $returnRecords.URL
    }
}

2 个答案:

答案 0 :(得分:1)

首先创建目标IP地址到包含URL的CSV中的URL的映射:

$urlmap = @{}
Import-Csv 'C:\path\to\SecondLog.csv' -Delimiter ';' |
  Group-Object Destination |
  ForEach-Object { $urlmap[$_.Name] = @($_.Group | Select-Object -Expand URL) }

然后将URL添加到缺少它们的文件中:

$csv = Import-Csv 'C:\Path\to\firstLog.csv' -Delimiter ';'
foreach ($record in $csv) {
  if ($urlmap.Contains($record.Destination)) {
    $record.URL = $urlmap[$record.Destination] -join ';'
  }
}
$csv | Export-Csv 'C:\Path\to\firstLog.csv' -Delimiter ';' -NoType

答案 1 :(得分:0)

试一试。如果我理解正确的话,它应该做你需要的。如果没有,它会让你真正接近。

$noUrlFilePath = 'C:\NoUrls.txt'
$urlFilePath = 'C:\Urls.txt'

$noUrlRows = Import-Csv -Path $noUrlFilePath -Delimiter ';'
$urlRows = Import-Csv -Path $urlRows -Delimiter ';'

foreach ($urlRow in $urlRows) {
    foreach ($noUrlRow in $noUrlRows) {
        if ($urlRow.Destination -eq $noUrlRow.Destination) {
            $noUrlRow.URL = $urlRow.URL
        }
    }
}

$noUrlRows | Export-Csv -Path 'C:\FinishedLog.txt' -Delimiter ';'