Powershell脚本逐行读取文件,将以特定字符串开头的行传递给函数

时间:2015-11-02 22:08:25

标签: powershell

我试图使用Sonarqube获取代码覆盖率。覆盖率报告由业力生成。由于某种原因,Karma生成的覆盖文件发生了变化 报告中有22个文件的情况。结果,我无法覆盖这22个文件。我在Jenkins中使用PowerShell脚本生成规范路径。下面是脚本。我的脚本应该执行以下步骤:

  1. 访问覆盖率报告(unit-tests-lcov.info)
  2. 逐行阅读报告
  3. 使用' SF'开头的unit-tests-lcov.info中的每个文件。并将其传递给规范函数
  4. 保存文件
  5. 我无法为第3步编写脚本。任何人都可以在下面对我的脚本进行必要的更改吗?

    $getPathNameSignature = @'
    [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern uint GetLongPathName(
        string shortPath, 
        StringBuilder sb, 
        int bufferSize);
    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError=true)]
    public static extern uint GetShortPathName(
       string longPath,
       StringBuilder shortPath,
       uint bufferSize);
    '@
    $getPathNameType = Add-Type -MemberDefinition $getPathNameSignature -Name GetPathNameType -UsingNamespace System.Text -PassThru
    
    
    function Get-PathCanonicalCase
    {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # Gets the real case of a path
            $Path
        )
    
        if( -not (Test-Path $Path) )
        {
            Write-Error "Path '$Path' doesn't exist."
            return
        }
    
        $shortBuffer = New-Object Text.StringBuilder ($Path.Length * 2)
        [void] $getPathNameType::GetShortPathName( $Path, $shortBuffer, $shortBuffer.Capacity )
    
        $longBuffer = New-Object Text.StringBuilder ($Path.Length * 2)
        [void] $getPathNameType::GetLongPathName( $shortBuffer.ToString(), $longBuffer, $longBuffer.Capacity )
    
        return $longBuffer.ToString()
    }
    
    $file3 = "$env:WORKSPACE\UIArtifacts\unit-tests-lcov.info"           
    $text = (Get-Content -Path $file3 -ReadCount 0) -join "`n"  
    $ran = $text -Includes 'SF'                                  
    Get-PathCanonicalCase($text) | Set-Content -Path $file3    
    

    输入文件的一部分如下所示: 我需要将文件路径传递给Get-Canonical函数。 PS。部分文件路径是环境变量。

    TN:
    c:\sysapps\hudson\.jenkins\jobs\CropObsUi-Metrics\workspace\encirca\encConf.js
    FNF:0
    FNH:0
    DA:10,1
    DA:14,1
    DA:30,1
    DA:31,1
    DA:32,1
    DA:33,1
    DA:34,1
    DA:35,1
    DA:36,1
    DA:37,1
    DA:39,1
    LF:11
    LH:11
    BRF:0
    BRH:0
    end_of_record
    TN:
    c:\sysapps\hudson\.jenkins\jobs\CropObsUi-Metrics\workspace\encirca\common\util\data.js
    FN:25,(anonymous_1)
    FN:57,(anonymous_2)
    FN:87,(anonymous_3)
    FN:149,(anonymous_4)
    FNF:4
    FNH:0
    FNDA:0,(anonymous_1)
    FNDA:0,(anonymous_2)
    FNDA:0,(anonymous_3)
    FNDA:0,(anonymous_4)
    

1 个答案:

答案 0 :(得分:1)

好的,问题简短列表。我认为-join命令没有理由。通常,Get-Content cmdlet将以字符串数组的形式读取文本文件,每行为一个字符串。当您加入它们时,它将转换为一个多行字符串。这完全违背了你的目的。

$text = Get-Content -Path $file3

您可以使用Where语句和-like运算符过滤行。

$ran = $text | Where{$_ -like "SF*"}

调用函数时,通常采用正确的格式:

FunctionName -Parameter Value [-AdditionalParameters AdditionalValues]

您可以省略参数名称,并在大多数情况下按顺序放置值。所以你的最后一行应该是:

Get-PathCanonicalCase $ran | Set-Content -Path $file3

那只会输出以SF开头的行,而且我不确定它是如何工作的,因为我不认为路径将从SF开始。我觉得还有更多的东西,这不会像你期望的那样处理你的问题。该函数期望传递给它的字符串是路径,而只是路径。它不期望必须从更长的字符串中解析路径。

确定传递给函数:

c:\temp\somefile.csv

传递给函数不正常:

SF: c:\temp\somefile.csv <8,732 KB> 11/3/2015 08:16:32.6635

我不知道你的文件中的行是什么样的,所以我只是随机地编写了这个,但关键是如果你的路径是你传递给函数的子串,那么函数不会起作用。我认为你需要一些额外的逻辑来完成这项工作。

但是,这确实回答了关于如何将以SF开头的文件的每一行传递给函数的问题。

编辑2:好的,我认为在删除SF之前你可能会更好:从包含路径的行开始。这就是为什么...... SF:可以很容易地知道哪些行需要传递给函数,而其他行可以简单地通过。修剪&#34; SF:&#34;一开始很容易。因此,我们将使用RegEx将路径替换为该功能提供的更新路径。我们将使用&#39; SF:&#39;找出路径的位置。我们走了......

首先像您一样导入文件,但不要-join它(如上所述)。

$text = Get-Content -Path $file3

然后我们将跳过整个$ran =位,因为它不需要它。相反,我们将$text传递到ForEach循环,并在该循环中查看该行。如果该行以SF开头:我们将其替换为&#34; SF:&#34;然后输出函数。对于函数,我们向它发送一个从当前行的第4个字符开始的子字符串,因此它会跳过&#39; SF:&#39;并且只获得路径。如果它不是SF:行,我们只需输出不变的行。

$text |%{If($_ -like "SF:*"){"SF:$(Get-PathCanonicalCase $_.substring(3))"}else{$_}} | Out-File $file3