当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 文字游戏

作者:精品下载站 日期:2024-12-14 07:58:41 浏览:15 分类:玩电脑

PowerShell 文字游戏


几周前,Iron Scripter PowerShell 发起了一项挑战,其中涉及文字和字符的游戏。请记住,Iron Scripter 挑战并不是为了创建有意义的、具有生产价值的代码。它们旨在帮助您学习 PowerShell 基础知识和脚本技术。这项特殊的挑战针对初学者和中级经验水平。我有自己的解决方案可以分享,但它们不一定是唯一的解决方案,甚至不是最好的解决方案。

初学者

初学者挑战要求您获取一个字符串并计算其字符值的总和。当然,你首先需要一根绳子。

$w = "PowerShell Iron Scripter"

每个字母实际上由一个[CHAR] 表示。从技术上讲,该字符串是 System.Char 对象的数组。如果你运行:

$w[0] | Get-Member

您可以验证这一点。 $w[0] 是字符数组中的第一个元素。

不太清楚的是这个对象有一个底层的整数值。尝试这个:

$w[0] -as [int]

此命令告诉 PowerShell 将对象 $w[0] 视为整数。您应该得到 80 的值。事实上,如果您运行以下命令:

[char]80

你应该得到 P 的结果。顺便说一句,你也可以这样计算整数值:

 $w[0].ToInt32($null)

但这不是我希望初学者知道的事情。

有了这些知识,就可以计算所有字符的总和了。希望您了解测量对象。您可以使用单个角色进行快速测试。

$w[0] | Measure-Object -sum

您应该看到 Sum 值为 80。请确保您了解此模式。您告诉 PowerShell,“取出管道 (|) 左侧的所有字符并将它们发送到 Measure-Object。让 cmdlet 获取总和。不需要指定属性,因为 [CHAR] 对象实际上没有任何属性。一旦您认识到这种模式,就可以轻松地进行下一步,将字符串转换为字符数组。如果将 $w 通过管道传递给 Get-Member,您将看到此方法。

$w.toCharArray()

在屏幕上,PowerShell 会将这些值显示为您可以读取的内容。但您实际上可以按照您刚才发现的模式将此数组发送到 Measure-Object。

$w.toCharArray() | Measure-Object -sum | Select-Object -property Sum

我采取下一步将测量对象结果通过管道传输到 Select-Object 以仅显示 Sum 属性。当您运行此命令时,您仍然会得到一个具有单个属性 Sum 的对象。如果您只需要该值,可以告诉 Select-Object 展开该属性。

$w.toCharArray() | Measure-Object -sum | Select-Object -expandproperty Sum

您应该能够通过阅读 Select-Object 的帮助和示例来发现这一点。

了解 PowerShell 管道后,您可以将命令简化为:

($w.ToCharArray() | Measure-Object -sum).sum

您告诉 PowerShell,运行括号内的代码(您可以这样做,以便您可以看到发生了什么),然后显示该对象的 Sum 属性。使用 $w 中的文本,您应该得到总计 2345。

初学者挑战的第二部分是将数组转换为整数值的字符串。您已经知道如何创建数组。下一步是将它们显示为整数值。

$w.ToCharArray() | ForEach-Object {$_ -as [int] }

这将创建另一个数组。要将它们连接在一起,您可以使用 -Join 运算符,您可以通过搜索帮助找到该运算符。

help join

使用上面的嵌套管道模式,可以通过一行命令将文本转换为相应整数值的字符串。

($w.ToCharArray() | ForEach-Object {$_ -as [int] }) -join " "

或者您可以使用这个稍微高级的替代方案。

[int[]]$w.ToCharArray() -join " "

该命令告诉 PowerShell 将 ToCharArray() 方法的结果转换为整数数组。然后将该结果与每个值之间的空格连接起来。

如果您运行的是 PowerShell 7,您还有另一个选择,那就是名为 Join-String 的 cmdlet。

[int[]]$w.ToCharArray() | Join-String -Separator " "

中间的

下一个级别的挑战是利用这些知识并编写一组函数来使用双倍字符值创建字符串。让我们从一个新的文本字符串开始。

$t = "Today, I am a PowerShell Iron Scripter!"

这是一些概念验证代码。

$c = $t.ToCharArray() | ForEach-Object -begin {$out = @()} -process {
    $val = [int]([char]$_)
    $nval = $val*2
    $out += [char]$nval
} -end { $out -join ""}

第一部分与您作为初学者所做的类似。该数组通过管道传输到 ForEach-Object。大多数人可能习惯于使用单个脚本块(即进程脚本块)来运行它。代码为每个通过管道传入的对象运行一次,使用 $_ 作为占位符来指示当前对象。但也有开始和结束脚本块。在 Begin 块中,您可以定义一个数组 $out。这在任何管道处理完成之前完成一次。在进程块中,检索 [CHAR] 对象的整数值。通过乘以 2 计算出一个新值,然后将该新值转换回添加到数组中的 [CHAR]。最终,您将有足够的经验将这几行代码减少为一行,但我想确保您可以想象正在发生的事情。 End scriptlbock 中的代码在管道中的所有内容处理完毕后运行一次。您可以加入这些值。这些脚本块与您在创建高级 PowerShell 函数时使用的脚本块相同。

你应该得到一个看起来很奇怪的结果。

¨ÞÈÂòX@’@ÂÚ@Â@ ÞîÊä¦ÐÊØØ@’äÞÜ@¦ÆäÒàèÊäB

根据 [CHAR] 值,您甚至可能会得到非打印字符。要反转该过程,只需将每个 [CHAR] 整数值除以 2 即可。

$c.ToCharArray() | ForEach-Object -begin {$out = @()} -process {
    $val = [int]([char]$_)
    $nval = $val/2
    $out += [char]$nval
} -end { $out -join ""}

这将输出原始字符串。现在您已经有了工作代码,您可以围绕它们构建函数。

Function ConvertTo-DoubleChar {
    [cmdletbinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$Text
    )

    Begin {
        Write-Verbose "[BEGIN  ] Starting: $($MyInvocation.Mycommand)"
    } #begin

    Process {
        Write-Verbose "[PROCESS] Converting $text"

        $Text.ToCharArray() | ForEach-Object -begin {
            $out = @()
        } -process {
            $val = [int]([char]$_)
            $nval = $val*2
            $out += [char]$nval
        } -end {
            $converted  = $out -join ""
        }
        Write-Verbose "[PROCESS] to $converted"
        $converted
    } #process
    End {
        Write-Verbose "[END    ] Ending: $($MyInvocation.Mycommand)"
    } #end
}

Function ConvertFrom-DoubleChar {
    [cmdletbinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$Text
    )

    Begin {
        Write-Verbose "[BEGIN  ] Starting: $($MyInvocation.Mycommand)"
    } #begin

    Process {
        Write-Verbose "[PROCESS] Converting $text"

        $Text.ToCharArray() | ForEach-Object -begin {
            $out = @()
        } -process {
            $val = [int]([char]$_)
            $nval = $val/2
            $out += [char]$nval
        } -end {
            $out -join ""
        }
    } #process
    End {
        Write-Verbose "[END    ] Ending: $($MyInvocation.Mycommand)"
    } #end
}

我们来做一个“往返”测试。

"PowerShell is wicked fun!" | ConvertTo-DoubleChar -OutVariable in | ConvertFrom-DoubleChar

如果函数设计正确,纯文本字符串将转换为其双 [CHAR] 版本,然后再转换回来。

PS C:\> "PowerShell is wicked fun!" | ConvertTo-DoubleChar -OutVariable in | ConvertFrom-DoubleChar
PowerShell is wicked fun!

为了双重验证,我的示例使用公共参数 OutVariable 来保存 ConvertTo-DoubleChar 的结果。

PS C:\> $in
 ÞîÊä¦ÐÊØØ@Òæ@îÒÆÖÊÈ@ÌêÜB

PS C:\> ConvertFrom-DoubleChar $in
PowerShell is wicked fun!

这是管道多个字符串的另一个示例。

[玩转系统] PowerShell 文字游戏

正如我在一开始提到的,这些并不是唯一的解决方案。学习 PowerShell 没有捷径。您需要养成阅读帮助的习惯。开发可以重复使用的模式和实践。一旦熟悉了基础知识,无论您使用的是角色对象、服务还是 Azure 虚拟机,都不再重要。

如果您对我的想法有任何疑问,请在评论中提问。

了解更多

如果您正在寻找更多方法来测试和自学 PowerShell,我鼓励您获取《PowerShell 实践入门》的副本。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯