获取.ps1文件中特定函数的最后一行

Phi*_*ani 2 powershell function powershell-3.0

我想在.ps1文件中获取特定函数的最后一行.我已经用powershell v3代码完成了这个:

function GetEndLineNumber($ParseFile, $functionName))
{
    $AbstractSyntaxTree = $NewParser::ParseFile($ParseFile, [ref]$null,  [ref]$null)
    $functionsInFile = $AbstractSyntaxTree.FindAll({$args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $true)
    #endregion

    $initializeFunction = $null
    foreach($function in $functionsInFile)
    {
        if($function.Name -eq $functionName)
        {
            $initializeFunction = $function
            break
        }
    }

    if($initializeFunction -eq $null){ return 0 }

    $initializeFunctionBody = $initializeFunction.Body

    return $initializeFunctionBody.Extent.EndLineNumber
}
Run Code Online (Sandbox Code Playgroud)

但是这个脚本也应该在v2上运行,我尝试使用System.Management.Language.PSParser和ScriptBlock.但没有任何成功.有人知道如何在.ps1文件中获取特定函数名的最后一行(作为int或字符串)?

编辑:

我想这里有一些误解:我想在.ps1脚本中获取特定函数的最后一行.不是函数中特定函数的最后一行.因为我必须在最后添加我自己的代码到这个函数这里一个简单的例子我的脚本看起来如何:

test.ps1

1function test321
2 {
3  Write-Host "test3142"
4 }
5
6function test1
7{
8 if($true)
9 {
10  Write-Host "hello"
11 }
12 #comment
13 
14 Write-host "end"
15 
16}
17
18function test2
19{
20 #bla
21}
Run Code Online (Sandbox Code Playgroud)

我想要一个名为GetEndLineNumber($ scriptFile,$ functionName)的函数,它应该像这样工作:

test2.ps1

$path = "C:\Scripts\test.ps1"
$lastLine = GetEndLineNumber $path "test1"

$lastLine should be in this case 15 or 16.
Run Code Online (Sandbox Code Playgroud)

Rom*_*min 5

在PowerShell V2中,我们可以使用System.Management.Automation.PSParser生成的标记来自行解析:

function GetEndLineNumber {
    param(
        $scriptFile,
        $functionName
    )

    $code = Get-Content -LiteralPath $scriptFile
    $tokens = [System.Management.Automation.PSParser]::Tokenize($code, [ref]$null)

    $waitForFuncName = $false
    $funcFound = $false
    $level = 0

    foreach($t in $tokens) {
        switch($t.Type) {
            Keyword {
                if ($t.Content -eq 'function') {
                    $waitForFuncName = $true
                }
            }
            CommandArgument {
                if ($waitForFuncName) {
                    $waitForFuncName = $false
                    $funcFound = $t.Content -eq $functionName
                }
            }
            GroupStart {
                ++$level
            }
            GroupEnd {
                --$level
                if ($funcFound -and $level -eq 0 -and $t.Content -eq '}') {
                    return $t.StartLine
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有彻底测试它,但我尝试了一些函数和脚本,它返回正确的行号.