灵活的PowerShell功能,用于处理文本内容

Faj*_*iya 1 powershell pipeline

我正在尝试编写一个在处理文本内容方面非常灵活的PowerShell函数。这个想法是能够从管道传递一个字符串,我的函数将在“\r?\n”处分割它以获取字符串数组,然后处理它。我还希望能够传递一个对象数组,并让我的函数使用 Out-String 将每个元素转换为字符串,然后对其进行处理。此外,我希望能够传递 FileInfo 对象数组,并让我的函数为我读取所有文件内容。然而,我正在努力让它发挥作用。看来PowerShell要求我使用类型或名称来获取管道对象。有没有办法强制它将管道对象传递给我的参数之一?

更新

这就是我现在所拥有的。显然它不起作用。该$content参数根本无法获取管道对象。例如,dir | Test不起作用。

Function Test {
    [Cmdletbinding()]
    Param(
        [Parameter(ValueFromPipeline = $true, Position = 0)] [Object] $content
    )

    Begin {
        if ($content -is [String]) {
            $content = [regex]::Split($content, "\r?\n")
        }
        if ($content -is [System.IO.FileInfo[]]) {
            $content = $content | ForEach-Object { $_.readalltext() }
        }

        if ($content -is [Array] -and $content -isnot [String[]]) {
            $content = $content | ForEach-Object { $_ | Out-String }
        }

    }
    Process {

        Write-Host $content.GetType()
        $content | ForEach-Object {
            Write-Host $_
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

San*_*zon 5

您试图确定$content来自管道的内容,并且您的代码总体上看起来不错,但是当您应该在 block 中执行此操作时,您却在函数块中begin执行process操作。从管道绑定时,块$content中尚不存在。begin

另外,你将不得不重新定义你的最后一个条件:

$content -is [Array] -and $content -isnot [String[]]
Run Code Online (Sandbox Code Playgroud)

数组的元素通过管道一一传递,通过强制从管道传递整个数组的情况非常罕见。最后一个条件很可能永远无法满足。

以下是您如何开始处理逻辑,有关详细信息,请参阅内联注释。

Function Test {
    [Cmdletbinding()]
    Param(
        [Parameter(ValueFromPipeline = $true, Position = 0)]
        [Object] $Content
    )

    Begin {
        # this list is used on the last condition
        $list = [System.Collections.Generic.List[object]]::new()
    }
    Process {
        # if content has new line characters
        # then we're dealing with a multi-line string
        if ($Content -match '\r?\n') {
            # split it and output it
            $Content -split '\r?\n'
        }
        # else if content is a FileInfo instance
        elseif ($Content -is [System.IO.FileInfo]) {
            # read it and output its content as a multi-line string
            $Content | Get-Content -Raw
        }
        # else, none of the above was met
        # you need to determine what you want to do here
        else {
            # we can capture each element from the pipeline
            # and then output it in the `end` block
            $list.Add($Content)
        }
    }
    end {
        # no more objects coming from pipeline
        # check if the list was populated
        if($list.Count) {
            # if it was, output the captured objects
            # as a string
            $list.ToArray() | Out-String
        }
    }
}
Run Code Online (Sandbox Code Playgroud)