-1

因此,我正在尝试按照Ryker Exum中定义的手动指南来自动化合并多个 Nessus 扫描的过程。我面临的挑战是我必须在文件中查找和删除行直到并包括某个点(一旦找到特定字符串)。我的目标是尽可能高效地执行此操作,因为其中一些 Nessus 扫描结果(XML 文件)可能超过 100MB。因此,我的方法是:

  1. 放置一些逻辑来识别第一个和最后一个文件,并对它们采取相应的行动。
  2. 删除除我遇到的第一个扫描文件之外的所有文件的最后 33 个字符。
  3. 获取每个文件的内容,一次一个地读取每个对象。如果没有匹配,删除该行并移动到下一个对象。如果有匹配,删除该行并停止(因此执行直到)。

在这一点上,我还没有成功完成第三步。代码如下:

$first = Get-ChildItem ".\" -Filter *.nessus | Select-Object -first 1
$last = Get-ChildItem ".\" -Filter *.nessus | Select-Object -last 1

if ($first -ne $last)
{
    Get-ChildItem ".\" -Filter *.nessus | Foreach-Object {

        $filepath = $_.FullName

        if ($first -eq  $_ -and $last -ne $_)
        {
            $stream = [System.IO.File]::OpenWrite($_.FullName)
            $stream.SetLength($stream.Length - 33)
            $stream.Close()
            $stream.Dispose()
        }

        if ($first -ne  $_ -and $last -ne  $_)
        {
            $stream = [System.IO.File]::OpenWrite($_.FullName)
            $stream.SetLength($stream.Length - 33)
            $stream.Close()
            $stream.Dispose()

            $found = ""

            do
            {
                Get-Content $_.FullName | Foreach-Object {

                    $found = $_.Contains("<Report name=")

                    if ($found)
                    {
                        Where-Object {$_ -match '<Report name='} | Set-Content $filepath
                    } else {
                        Where-Object {$_ -notmatch '<Report name='} | Set-Content $filepath
                    }
                }
            } until ($found)
        }

        if ($last -eq  $_ -and $first -ne $_)
        {
            $found = ""

            do
            {
                Get-Content $_.FullName | Foreach-Object {

                    $found = $_.Contains("<Report name=")

                    if ($found)
                    {
                        Where-Object {$_ -match '<Report name='} | Set-Content $filepath
                    } else {
                        Where-Object {$_ -notmatch '<Report name='} | Set-Content $filepath
                    }
                }
            } until ($found)
        }
    }
}

任何人的想法或评论?

4

1 回答 1

0

我认为这看起来真的很复杂。相反,我会检查它是否是第一个文件,如果是,我会告诉它不要跳过任何行,如果它不是第一个文件,我会让它找到那个<Report name=字符串,并跳过所有行,包括那个.

然后我会检查它是否是最后一个文件,如果是,我会让它读取文件的整个其余部分,但如果它不是最后一个文件,我会让它读取除了文件的最后两行之外的所有文件它可能正在阅读什么。

一旦我知道在文件的开头和/或结尾要跳过多少行,我就会让它读取适当的行,然后输出到一个新文件,根据需要附加。所有这些的代码如下所示:

$First = GCI ".\" -Filter *.nessus|Select -First 1
$Last = GCI ".\" -Filter *.nessus|Select -Last 1
GCI GCI ".\" -Filter *.nessus|%{
    If($_.Name -ne $First.Name){$SkipLines = (Select-String -Path $_.FullName -SimpleMatch "<Report name="|select -expand LineNumber)+1}else{$SkipLines = 0}
    If($_.Name -ne $Last.Name){$ReadLines = (GC $_.FullName).Count - 2 - $SkipLines} else {$ReadLines = (GC $_.FullName).Count - $SkipLines}
    GC $_.FullName | Select -First $ReadLines -Skip $SkipLines | Out-File ".\Merged.nessus" -Append
}
于 2014-05-30T20:21:11.653 回答