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

vngu2lb8  于 2023-02-16  发布在  Shell
关注(0)|答案(1)|浏览(194)

我正在尝试编写一个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 $_
        }
    }
}
lymgl2op

lymgl2op1#

您试图确定来自管道的$content是什么,并且您的代码总体上看起来不错,但您在函数的begin块中这样做,而您应该在process块中这样做。当从管道绑定时,$content还不存在于begin块中。
另外,你必须重新定义最后一个条件:

$content -is [Array] -and $content -isnot [String[]]

数组的元素是一个接一个地通过管道传递的,通过强制管道传递整个数组是非常罕见的情况。最后一个条件可能永远不会满足。
下面是您可以如何开始处理逻辑的方法,详细信息请参见内联注解。

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
        }
    }
}

相关问题